We'll use the combined file method (i.e., the first method presented) as was used in the prior example. Start by creating Seq_Mode1.Ptr as before, so the Assembler doesn't complain about a missing file. Create a new file named Only_Mode1.Asm and and place this first title and documentation block in it.
/****************************************************************************** * * Routine "SetSameColor" * * Purpose: Output a single color to all pixels specified by LED count. * * Assumes: This routine is a FOREGROUND task (so R15 is valid upon entry.) * R29:R28 points to the start of the uVars.B[] array * R1 contains the value 0 * * Passed: R24 byte wOffset into the uVars.B[] array for our 16 bytes * if invalid (e.g., 0xFF), 0 will be used instead * * Alters: * * Notes: The WS2812 configuration block (or structure) layout: * +---------+-----------+--------+----------+---------+----+----+-/ * | Display | Bitmapped | Port's | (Inc/Dec | (MaxBrt | LED | * | Mode |GRB| | Port| Pin(s) |unused) | unused) | Count | . . . * +---------+-3-+1+--4--+--------+----------+---------+----+----+-/ * +0 +1 +2 +3 +4 +5 +6 * +7 +8 +9 +10, 11 +12, 13 +14 +15 * /-+----+----+----+----+-----+------+------+-----+-----+ * | Mode Specific| Update | Mode Change | Starting | * . . . | #1 | #2 | #3 | Interval | Interval | Address | * /-+----+----+----+----+-----+------+------+-----+-----+ * Green Red Blue milliSec Seconds * * * The GRB (Green-Red-Blue) LED BYTE data image layout: * +-----+-----+-------+-------+-------+-------+-------+-------+-/ * | Byte Count| Green | Red | Blue | Green | Red | Blue | * | LSB MSB | LED#1 | LED#1 | LED#1 | LED#2 | LED#2 | LED#2 | . . . * +-----+-----+-------+-------+-------+-------+-------+-------+-/ * +0 +1 +2 +3 +4 +5 +6 +7 * ******************************************************************************/
The first two (2) BYTES of code in every Sequencer block are the unique Mode ID then the number of 16-BYTE "sentences" in the module. They're followed by the "LDI R30, I_PushAll" instruction. The code for this Sequencer block is very small, since all it is doing is writing the same 3-BYTE color code to each of the pixels specified.
.IFNDEF ASetSameColor .PRINT "Assemble again to initialize label addresses." ASetSameColor = 0x102 AMode1End = 0x144 .ENDIF Mode1Start: .BYTE 1 ; The MODE byte: Mode 1 .BYTE (AMode1End - ASetSameColor) / 16 + 1 ; Number of 16-byte blocks used SetSameColor: ; Bytes Clocks LDI R30, I_PushAll ; 2 1 Select the routine: PushAll, which MUST RCALL ASoftVector ; 2 3 use a CALL, not a JUMP! RCALL AShared_Setup ; 2 3 Use 2-BYTE CALLs/JMP for this example Mode1_Loop: ; Begin the loop; 1 loop for each GRB LED pixel ST Z+, R17 ; 2 2 Write the LED color GREEN component ST Z+, R18 ; 2 2 Write the LED color RED component ST Z+, R19 ; 2 2 Write the LED color BLUE component SBIW R26, 1 ; 2 2 Decrement the remaining LED count WORD, BRNE AMode1_Loop ; 2 1/2 which is maintained in R27:R26 MOV R18, R12 ; 2 2 Shared_Output() needs bPortPins in R18 CPSE R18, R1 ; 2 1/2 If uVars.B[ n+2 ] is zero, there is no RCALL AShared_Output ; 2 3 need to call Shared_Output() RJMP AShared_Exit ; 2 2 Mode1End: .BALIGN 16, 0xFF, 15 ; Byte align to 16 boundary; pad with 0xFFs
Close the Only_Mode1.Asm file then concatenate it to the Seq_Mode0.Asm source from the last example. The copying and assembly results in the output below.
C:\TestDir> Copy /B Seq_Mode0.Asm+Only_Mode1.Asm Seq_Mode1.Asm Seq_Mode0.Asm Only_Mode1.Asm 1 file(s) copied. C:\TestDir>Assemble Seq_Mode1 Assemble again to initialize label addresses. C:\TestDir>Assemble Seq_Mode1 Assemble again to initialize label addresses.
We've encountered this before. Open the Seq_Mode1.Asm source code file and search for the ".INCLUDE Seq_Mode0.Ptr" line. It should still be located at about line 115. Only a single character needs to be changed: the "0" in that line, to a "1". Assemble it again. Since the prior Assembly already created the new line identifier label constants in the .Sym and .Ptr files, simple including the Seq_Mode1.Ptr file resolved all of the missing addresses so the final code contains the missing constants and the warning message is no longer generated.
Examine the Seq_Mode1.Dmp listing to verify that all the new branch instructions near the end of the file actually did resolve as expected. These should be the last few lines of the Seq_Mode1.Hex or Seq_Mode1.Trm iHex image file. The new Mode 1 Sequencer module has 26 BYTEs of code and six (6) BYTEs of 0xFF padding. Just as a reminder, this subroutine's code is NOT relocatable since it uses RCALL and RJMP operations to targets outside of the Sequencer Mode 1 subroutine.
> D+F-H 0x240 32 :100240000102E0E0DDDE64DF119321933193119729 :10025000D9F72C2D211195DFABCFFFFFFFFFFFFF5B :00000001FF >
This sequence isn't actually called very often since it can be quite jarring to have all of the LEDs quickly change intensity at the same moment. Still, it's here as an example. This is the Seqencer module code which results. It is only 32 BYTEs in length.