receiving serial data with smartpins
ersmith
Posts: 6,053
in Propeller 2
I'm trying to write a serial object for the P2 Eval board that uses smart pins instead of bitbanging DIRB, and I can get the transmit to work fine but I've done something stupid on receive. Could someone do a sanity check on my setup? I tried to base it on the ROM and the smartpin_serial_turnaround.spin2 demo file.
The code is below. As I mentioned, serial transmit works, so the clock setup and baud calculation are presumably correct. And I see the small LED next to the USB input flicker when I type characters in the terminal window, so I think the Windows terminal program is working (it is definitely receiving correctly, since I see the initial prompt).
The serial code:
The test program:
The code is below. As I mentioned, serial transmit works, so the clock setup and baud calculation are presumably correct. And I see the small LED next to the USB input flicker when I type characters in the terminal window, so I think the Windows terminal program is working (it is definitely receiving correctly, since I see the initial prompt).
The serial code:
' ' simple smart pin serial object for P2 Eval board ' CON _txmode = %0000_0000_000_0000000000000_01_11110_0 'async tx mode, output enabled for smart output _rxmode = %0000_0000_000_0000000000000_00_11111_0 'async rx mode, input enabled for smart input VAR long rx_pin, tx_pin PUB start(rxpin, txpin, mode, baudrate) | bitperiod, txmode, rxmode bitperiod := 7 + ((CLKFREQ / baudrate) << 16) rx_pin := rxpin tx_pin := txpin txmode := _txmode rxmode := _rxmode asm wrpin txmode, txpin wxpin bitperiod, txpin dirh txpin wrpin rxmode, rxpin wxpin bitperiod, rxpin dirl rxpin endasm return 1 PUB tx(val) | txpin, z txpin := tx_pin asm wypin val, txpin waitx #1 endasm z := 1 repeat while z <> 0 asm testp txpin wc if_c mov z, #0 endasm ' check if byte received (never waits) ' returns -1 if no byte, otherwise byte PUB rxcheck : rxbyte | rxpin, z rxbyte := -1 rxpin := rx_pin asm testp rxpin wc ' char ready? if_c rdpin rxbyte, rxpin if_c shr rxbyte, #24 endasm ' receive a byte (waits until one ready) PUB rx : v repeat v := rxcheck while v == -1 ' transmit a string PUB str(s) | c REPEAT WHILE ((c := byte[s++]) <> 0) tx(c) PUB dec(value) | i, x '' Print a decimal number result := 0 x := value == NEGX 'Check for max negative if value < 0 value := ||(value+x) 'If negative, make positive; adjust for max negative tx("-") 'and output sign i := 1_000_000_000 'Initialize divisor repeat 10 'Loop for 10 digits if value => i tx(value / i + "0" + x*(i == 1)) 'If non-zero digit, output digit; adjust for max negative value //= i 'and digit from value result~~ 'flag non-zero found elseif result or i == 1 tx("0") 'If zero digit (or only digit) output it i /= 10 'Update divisor PUB hex(val, digits) | shft, x shft := (digits - 1) << 2 repeat digits x := (val >> shft) & $F shft -= 4 if (x => 10) x := (x - 10) + "A" else x := x + "0" tx(x)
The test program:
OBJ ser: "SmartSerial.spin2" VAR BYTE name[128] PUB demo clkset(oscmode, freq) ser.start(63, 62, 0, baud) ser.str(string("Hello, there! What is your name? ")) getname ser.str(string("Nice to meet you ")) ser.str(@name[0]) PUB getname | c, i i := 0 repeat c := ser.rx ser.tx(c) if (c == 8) if i > 0 --i elseif c == 13 or c == 10 quit else name[i++] := c name[i] := 0
Comments
D'oh! I was thinking in terms of dumb pins, where the rxpin is set as an input by setting DIRA[pin] to 0. But you're right, for the smart pin I need dirh. Thanks!
Only local variables (inside functions) are in COG memory. The VAR variables are in HUB.
RIght now a 10kB local array probably won't work, but I plan on adding a check to force large arrays into HUB memory.
Also I guess if you ever copy/paste pasm code into this spin, you'd need to ensure the indenting is okay which could get tedious if you don't have the endasm.
eg Not shown in the example, are asm labels, but usually they are placed left of the code columns, so needs an explicit 'asm-zone' delimiting.