Using arrays in PASM2?
I decided to re-visit my previous attempt at designing a multi-port serial object. It is based on Jon's excellent FullDuplexSerial object (sorry Jon for butchering your code!) and my own ideas of how to implement multiple serial ports. To do this I decided to use several arrays to hold the variables.
long num_ports ' total number of open ports (0-7) long rxpins[MAX_PORT] ' rx pin array long txpins[MAX_PORT] ' tx pin array long rxhub[MAX_PORT] ' cog p_rxbuf - ptr to rxbuf hub address long txhub[MAX_PORT] ' cog p_txbuf - ptr to txbuf hub address long p_rxhd[MAX_PORT] ' cog ptr to rxhead hub address start long p_txhd[MAX_PORT] ' cog ptr to txhead hub address start long p_txtl[MAX_PORT] ' cog ptr to txtail hub address start long rxhead[MAX_PORT] ' rx/tx head and tail arrays long rxtail[MAX_PORT] long txhead[MAX_PORT] ' long txtail[MAX_PORT] '
The above are the arrays defined as global VARs in the spin code.
portnum long 1 ' total # ports rxpin long 0[MAX_PORT] ' rx pin array txpin long 0[MAX_PORT] ' tx pin array p_rxbuf long 0[MAX_PORT] ' ptr to rxhub p_txbuf long 0[MAX_PORT] ' ptr to txhub p_rxhead long 0[MAX_PORT] ' ptr to rxhead p_txhead long 0[MAX_PORT] ' ptr to txhead p_txtail long 0[MAX_PORT] ' prt to txtail
And above are the variables located in the DAT section of PASM2 (along with a few other working variables).
In the attached SPIN document the AddPort() method initializes the rx/tx smart pins and stores the number of open ports prior to running the start() method to initialize the cog
uart_mgr ' read hub arrays into cog, get # of open ports ' to copy to cog ram rdlong portnum, ptra++ ' get # of open ports setq #(MAX_PORT*7) ' block copy hub variables to cog rdlong rxpin, ptra uart_main ' loop through each port, get rx, tx pins mov portctr, #0 ' initialize portctr = 0
(I cut out the numerous DEBUG statements in the code for clarity - I attached the full code to this thread) Starting out I move the SPIN variables into PASM2, this appears to be working correctly. The portctr based on the number of open ports and used to loop through each port to see if there is anything to receive or transmit.
.loop ' get offsets for array values alts portctr, #rxpin ' add portctr offset to rxpin - rxpin[portctr] mov rxd, 0 ' copy rxpin to rxd alts portctr, #txpin ' add portctr offset to txpin - txpin[portctr] mov txd, 0 ' copy txpin to txd ' rxpin available, jump to rx_serial or tx_serial testb rxd, #31 wc ' rx pin in use? -test for -1 when no pin saved if_nc call #rx_serial testb txd, #31 wc ' tx in use? -test for -1 if_nc call #tx_serial ' increment counter to next port. if portctr = ' open ports, reset portctr to 0 and loop incmod portctr, portnum wc ' check if portctr = open ports if_nc jmp #.loop ' repeat loop for each open port jmp #uart_main
The main loop here gets the rx, tx pins and sees if the smart pin has anything, then jumps to the tx or rx code. It loops through each open port. I am working on the tx_serial code at this point, haven't tested the rx_serial routine yet.
tx_serial rdpin t1, txd wc ' check busy flag if_c ret ' abort if busy alts portctr, #p_txhead ' get txhead value from hub mov offset, 0 ' offset = address of txhead[portctr] rdlong t1, offset ' t1 = txhead[portctr] in hub memory alts portctr, #p_txtail ' get txtail value from hub mov offset1, 0 ' offset1 = address of txtail[portctr] rdlong t2, offset1 ' t2 = txtail[portctr] in hub memory cmp t1, t2 wz ' byte(s) to tx? if_e ret alts portctr, #p_txbuf ' get txbuf[portctr] in hub memory mov t1, 0 ' t1 := txhub[portctr] add t1, t2 ' add tail index rdbyte t3, t1 ' t3 := txhub[txtail] wypin t3, txd ' load into sp uart incmod t2, #(BUF_SIZE-1) ' update tail index _ret_ wrlong t2, offset1 ' write tail index back to hub
Everything up to this point appears to be working right, the correct txpin is being used but I think I'm messing up in the way I'm using the p_txhead pointer array in the cog. I thought that this points back to the hub memory location for the txhead value but the DEBUG values are not what I'm expecting. Monitoring the txpin with a logic analyzer isn't giving me the expected output either. Obviously something is being sent to the tx pin so the tx_serial loop is triggered and I see the start bit on the analyzer but only '1's' are showing up after that.
I'm hoping some of the PASM gurus can see the error of my ways!