Skip to content

Commit

Permalink
Merge pull request #215 from ironsheep/master
Browse files Browse the repository at this point in the history
Upgrade to v0.2.0 Ironsheep LED Matrix Driver
  • Loading branch information
PropGit authored Feb 22, 2021
2 parents b6e0e21 + 51e17dc commit f6c5421
Show file tree
Hide file tree
Showing 11 changed files with 1,511 additions and 549 deletions.
7 changes: 5 additions & 2 deletions libraries/community/p2/All/isp_hub75_matrix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ Language: Spin2 / Pasm2

Created: 03-DEC-2020

Upadted: 19-FEB-2021

Category: display

Description:
Driver for HUB75 controlled RGB LED Matrix Panels

Related:

- See Docs, Setup Instructions at [HUB75 LED Matrix Driver Github Repository](https://github.com/ironsheep/p2-HUB75-LED-Matrix-Driver)
- Watch for P2 Eval HUB75 Driver Board soon to be for sale at [Parallax Shop](https://www.parallax.com/product-category/propeller-2/)
- See Docs, Setup Instructions at [HUB75 LED Matrix Driver Github Repository](https://github.com/ironsheep/p2-LED-Matrix-Driver)
- Buy P2 Eval HUB75 Driver Board at [Parallax Online Store](https://www.parallax.com/product/p2-eval-hub75-adapter-board/)
- See Morphing Digits software add-on at the [P2 LED-Matrix Morphing Digits Repository](https://github.com/ironsheep/P2-LED-Matrix-Morphing-Digits)

License: MIT (see end of source code)
26 changes: 23 additions & 3 deletions libraries/community/p2/All/isp_hub75_matrix/isp_hub75_color.spin2
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,27 @@ CON { test colorset }
cOrange = $FFA500
cBlueViolet = $8A2BE2

cFullRed = $FF0000
cFullGreen = $00FF00
cFullBlue = $0000FF

' SPECIAL non-colors - invoke alforithm to gerate actual color used'
cRedWhtBlu = $deadf0
cRainbow = $deadf1

#0, LED_UNKNOWN, LED_RED, LED_GREEN, LED_BLUE

' our 3-bit colors
BASE_BLACK = $00
BASE_RED = $01
BASE_GREEN = $02
BASE_YELLOW = $03
BASE_BLUE = $04
BASE_MAGENTA = $05
BASE_CYAN = $06
BASE_WHITE = $07


OBJ

screen : "isp_hub75_screenAccess"
Expand Down Expand Up @@ -152,14 +167,19 @@ PUB dutyCycleForIntensity(hex8bit) : pwmBits
'' CALCULATE: proper duty cycle for intensity of 0-255
' --- VERSION 1 - Bits spread throughout ---
if hex8bit == 255
pwmBits := $ff
pwmBits := screen.MAX_PWM_FRAMES
else
pwmBits := hex8bit / screen.MAX_PWM_FRAMES


{
if not didShow[hex8bit]
debug("clr:dcyc ", uhex_byte(hex8bit), uhex_byte(pwmBits))
didShow[hex8bit] := TRUE
'}

DAT { tables, default values }

didShow byte FALSE[256]

defaultBrightness word 256 '256 ' 205 = 80% [0-255,256] where 256 is NO brightness adjustment

' Gamma curve (lookup table)
Expand Down
Git LFS file not shown
120 changes: 85 additions & 35 deletions libraries/community/p2/All/isp_hub75_matrix/isp_hub75_display.spin2
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ SCROLL_FOREVER = scroller.SCROLL_FOREVER
SCROLL_ONCE = scroller.SCROLL_ONCE
SCROLL_ONCE_TO_CLEAR = scroller.SCROLL_ONCE_TO_CLEAR

' FIXME: UNDONE make this user configurable
MAX_SCROLLING_REGIONS = 3

DAT { one or more screens of pixels of 24bit color }
Expand Down Expand Up @@ -66,18 +67,31 @@ VAR { Object Instance Variables }
byte horizontalGapInPix
byte verticalGapInPix
byte hBitmapOffsetInPix
byte bScan_1_4
byte bSwapRB

PUB start() : ok | scrollerIndex
PUB start() : ok | scrollerIndex, dvrConfig, driverConfigRaw
'' Start the underlying driver(s)

ok := cog := -1 ' mark as failed, initially

'debug("`term temp size 80 50 textsize 10")
if screen.MAX_PANELS_PER_COLUMN * screen.MAX_PANELS_PER_ROW <> screen.MAX_PANELS
debug("dsp:Geometry BAD in isp_hub75_hwGeometry.spin2!")
abort


debug("- TEXT: start()")
debug("dsp:start()")
ok := cog := panel.start() ' send buffer to driver
if ok == -1
debug("- TEXT: underlying drivers failed!")
debug("dsp:underlying drivers failed!")
abort

dvrConfig, driverConfigRaw := screen.getDriverFlags()
bScan_1_4 := (dvrConfig & screen.SCAN_4) > 0 ? True : False
bSwapRB := (dvrConfig & screen.RB_SWAP) > 0 ? True : False


' tell all about location of screen buffer
screen.setScreen(@screen0)

Expand All @@ -104,18 +118,23 @@ PUB clearScreen()

PUB fillScreen(rgbColor) | row, column
'' Fill the display with 24-bit color value
repeat row from 0 to screen.MAX_DISPLAY_ROWS - 1
repeat column from 0 to screen.MAX_DISPLAY_COLUMNS - 1
repeat row from 0 to screen.MAX_PHYSICAL_ROWS - 1
repeat column from 0 to screen.MAX_PHYSICAL_COLUMNS - 1
pixels.drawPixelAtRC(row, column, rgbColor)

PUB fillPanel(threeBitColor)
'' Fill screen but without PWM (for testing underlying driver)
panel.fillPanel(threeBitColor)

PUB commitScreenToPanel()
'' Write sceen to panel driver
'debug("- DISP: commit!")
panel.convertScreen2PWM(@screen0)
'' Write sceen to panel driver PWM frames (while alternating PWM frame sets)
'debug("dsp: commit!")

if bScan_1_4
panel.convertScreen2PWM_14(@screen0, bSwapRB)
'panel.convertScreen2PWM_14_spin(@screen0, bSwapRB)
else
panel.convertScreen2PWM(@screen0, bSwapRB)


{ -------------- Text Handling -------------- }
Expand Down Expand Up @@ -185,7 +204,7 @@ PUB setTextFont(newFont) | scrollerIndex, hUnusedPix, vUnusedPix

selectedTextFont := newFont

debug("dsp:font ", udec(charHeightInPix), udec(charWidthInPix), udec(maxTextLines), udec(maxTextColumns), udec(verticalGapInPix), udec(horizontalGapInPix), udec(topOffsetInPix), udec(leftOffsetInPix))
'debug("dsp:font ", udec(charHeightInPix), udec(charWidthInPix), udec(maxTextLines), udec(maxTextColumns), udec(verticalGapInPix), udec(horizontalGapInPix), udec(topOffsetInPix), udec(leftOffsetInPix))

' configure our scrollers for font choice
repeat scrollerIndex from 0 to MAX_SCROLLING_REGIONS - 1
Expand Down Expand Up @@ -310,7 +329,7 @@ PRI nextFreeScroller() : scrollerIndexToUse | scrollerIndex
if scrollerIndexToUse == NOT_FOUND
debug("Failed to locate free scroller!")
abort
debug("dsp:nextFreeScroller() ", udec(scrollerIndexToUse))
'debug("dsp:nextFreeScroller() ", udec(scrollerIndexToUse))

{ -------------- Basic Graphics -------------- }

Expand All @@ -324,25 +343,25 @@ PUB drawBoxOfColor(topRow, leftColumn, width, height, filled, rgbColor) | rightC
bottomRow := topRow + height - 1
if filled == TRUE
repeat rowIndex from 0 to height - 1
drawLineOfColor(topRow + rowIndex, leftColumn, topRow + rowIndex, rightColumn, currTextColor) ' horiz row
drawLineOfColor(topRow + rowIndex, leftColumn, topRow + rowIndex, rightColumn, rgbColor) ' horiz row
else
drawLineOfColor(topRow, leftColumn, topRow, rightColumn, currTextColor) ' horiz top
drawLineOfColor(topRow, rightColumn, bottomRow, rightColumn, currTextColor) ' vert right
drawLineOfColor(bottomRow, leftColumn, bottomRow, rightColumn, currTextColor) ' horiz bottom
drawLineOfColor(topRow, leftColumn, bottomRow, leftColumn, currTextColor) ' vert left
drawLineOfColor(topRow, leftColumn, topRow, rightColumn, rgbColor) ' horiz top
drawLineOfColor(topRow, rightColumn, bottomRow, rightColumn, rgbColor) ' vert right
drawLineOfColor(bottomRow, leftColumn, bottomRow, rightColumn, rgbColor) ' horiz bottom
drawLineOfColor(topRow, leftColumn, bottomRow, leftColumn, rgbColor) ' vert left


PUB drawLine(fmRow, fmColumn, toRow, toColumn)
'' Draw line fromRC -> toRC using current text color (currently limited to horzontal/vertical lines)
drawLineOfColor(fmRow, fmColumn, toRow, toColumn, currTextColor)

PUB drawLineOfColor(fmRow, fmColumn, toRow, toColumn, rgbColor) | row, column, dx, dy, ctr, incr
PUB drawLineOfColor(fmRow, fmColumn, toRow, toColumn, rgbColor) | row, column, dx, dy, ctr, incr, intD
'' Draw line fromRC -> toRC using rgbColor (currently limited to horzontal/vertical lines)
fmRow := 0 #> fmRow <# screen.MAX_PHYSICAL_ROWS - 1
fmColumn := 0 #> fmColumn <# screen.MAX_PHYSICAL_COLUMNS - 1
toRow := 0 #> toRow <# screen.MAX_PHYSICAL_ROWS - 1
toColumn := 0 #> toColumn <# screen.MAX_PHYSICAL_COLUMNS - 1
'debug("seg:drwLn fmRC=(", udec_(fmRow), ",", udec_(fmColumn), "), toRC=(", udec_(toRow), ",", udec_(toColumn), "), RGB=(", uhex_long(rgbColor), ")")
fmRow := 0 #> fmRow <# screen.MAX_DISPLAY_ROWS - 1
fmColumn := 0 #> fmColumn <# screen.MAX_DISPLAY_COLUMNS - 1
toRow := 0 #> toRow <# screen.MAX_DISPLAY_ROWS - 1
toColumn := 0 #> toColumn <# screen.MAX_DISPLAY_COLUMNS - 1
if fmRow == toRow
' draw Horizontal Line
repeat column from fmColumn to toColumn
Expand All @@ -352,22 +371,53 @@ PUB drawLineOfColor(fmRow, fmColumn, toRow, toColumn, rgbColor) | row, column, d
repeat row from fmRow to toRow
pixels.drawPixelAtRC(row, fmColumn, rgbColor)
else
dx := (toColumn - fmColumn)
dy := (toRow - fmRow)
if (abs(dx) >= abs(dy))
incr := abs(dx)
if abs(toRow - fmRow) < abs(toColumn - fmColumn)
if fmColumn > toColumn
plotLineLow(toColumn, toRow, fmColumn, fmRow, rgbColor)
else
plotLineLow(fmColumn, fmRow, toColumn, toRow, rgbColor)
else
incr := abs(dy)
dx := dx / incr
dy := dy / incr
column := fmColumn
row := fmRow
ctr := 1
repeat while (ctr <= incr)
pixels.drawPixelAtRC(row, column, rgbColor)
column += dx
row += dy
ctr += 1
if fmRow > toRow
plotLineHigh(toColumn, toRow, fmColumn, fmRow, rgbColor)
else
plotLineHigh(fmColumn, fmRow, toColumn, toRow, rgbColor)


PRI plotLineLow(x0, y0, x1, y1, rgbColor) | row, column, dy, dx, D, yi
dx := x1 - x0
dy := y1 - y0
yi := 1
if dy < 0
yi := -1
dy := -dy
D := (2 * dy) - dx
row := y0

repeat column from x0 to x1
pixels.drawPixelAtRC(row, column, rgbColor)
if D > 0
row := row + yi
D := D + (2 * (dy - dx))
else
D := D + 2 * dy

PRI plotLineHigh(x0, y0, x1, y1, rgbColor) | row, column, dy, dx, D, xi
dx := x1 - x0
dy := y1 - y0
xi := 1
if dx < 0
xi := -1
dx := -dx
D := (2 * dx) - dy
column := x0

repeat row from y0 to y1
pixels.drawPixelAtRC(row, column, rgbColor)
if D > 0
column := column + xi
D := D + (2 * (dx - dy))
else
D := D + 2*dx

{ -------------- Misc Helpers -------------- }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ PRI loadBitmap(pBitmapFile) | nPanelCol, nPanelRow, blue, green, red, haveError,
abort

' fill screen buffer
repeat nPanelRow from 0 to screen.MAX_PANEL_ROWS - 1
repeat nPanelCol from 0 to screen.MAX_PANEL_COLUMNS - 1
repeat nPanelRow from 0 to screen.MAX_PHYSICAL_ROWS - 1
repeat nPanelCol from 0 to screen.MAX_PHYSICAL_COLUMNS - 1
'debug("loadBitmap() - RC=(", udec_(nPanelRow), ", ", udec_(nPanelCol), ")")
showDebug := FALSE
if isDebugLocn(nPanelRow, nPanelCol)
Expand Down Expand Up @@ -101,7 +101,7 @@ PRI validateBmpFile(pBmpFileImage) : bValidStatus | pFileHeader, i, iStart, iEnd
' XYZZYpnl debug(" - Img-start @0x", uhex_(iStart))
' XYZZYpnl debug(" - Img-end @0x", uhex_(iEnd))

if biWidth <> screen.MAX_PANEL_COLUMNS or biHeight <> screen.MAX_PANEL_ROWS
if biWidth <> screen.MAX_PHYSICAL_COLUMNS or biHeight <> screen.MAX_PHYSICAL_ROWS
' XYZZYpnl debug(" !! invalid BMP size! [NOT 64x32]")
bValidStatus := FALSE

Expand All @@ -118,16 +118,16 @@ PRI validateBmpFile(pBmpFileImage) : bValidStatus | pFileHeader, i, iStart, iEnd
'else
' XYZZYpnl debug("-good BMP size! [64x32]")

'dbgMemDump(@fileHeaderMsg, pBmpFileImage, bfOffBits)
'dbgMemDump(@fileStartMsg, iStart, 32)
'dbgMemDump(@fileEndMsg, iEnd-32-1, 32)
'screen.dbgMemDump(@fileHeaderMsg, pBmpFileImage, bfOffBits)
'screen.dbgMemDump(@fileStartMsg, iStart, 32)
'screen.dbgMemDump(@fileEndMsg, iEnd-32-1, 32)

PRI get24BitBMPColorForRC(nRow, nColumn) : red, green, blue | pixColorAddr
if(nRow > screen.MAX_PANEL_ROWS - 1)
debug("- ERROR bad nRow value [", udec_(nRow), " > ", udec_(screen.MAX_PANEL_ROWS - 1), "]")
if(nRow > screen.MAX_PHYSICAL_ROWS - 1)
debug("- ERROR bad nRow value [", udec_(nRow), " > ", udec_(screen.MAX_PHYSICAL_ROWS - 1), "]")

if(nColumn > screen.MAX_PANEL_COLUMNS - 1)
debug("- ERROR bad nColumn value [", udec_(nColumn), " > ", udec_(screen.MAX_PANEL_COLUMNS - 1), "]")
if(nColumn > screen.MAX_PHYSICAL_COLUMNS - 1)
debug("- ERROR bad nColumn value [", udec_(nColumn), " > ", udec_(screen.MAX_PHYSICAL_COLUMNS - 1), "]")

pixColorAddr := getPixelAddressForBMPRowColumn(nRow, nColumn)
' our intername .bmp file byte order is BGR!
Expand All @@ -137,7 +137,7 @@ PRI get24BitBMPColorForRC(nRow, nColumn) : red, green, blue | pixColorAddr

PRI getPixelAddressForBMPRowColumn(nRow, nColumn) : pixColorAddr | rowIndex, columnIndex, nOffset, fileBitsBase, showDebug
' Row is inverted in .BMP file...
rowIndex := (screen.MAX_PANEL_ROWS - 1) - nRow
rowIndex := (screen.MAX_PHYSICAL_ROWS - 1) - nRow

' Column is normal in file...
columnIndex := nColumn
Expand All @@ -148,7 +148,7 @@ PRI getPixelAddressForBMPRowColumn(nRow, nColumn) : pixColorAddr | rowIndex, col
showDebug := TRUE ' FALSE ' turn off debug

' now offset is simple (just multiply by 3! [bytes of color])
nOffset := ((rowIndex * screen.MAX_PANEL_COLUMNS) + columnIndex) * screen.DISPLAY_BYTES_PER_COLOR
nOffset := ((rowIndex * screen.MAX_PHYSICAL_COLUMNS) + columnIndex) * screen.DISPLAY_BYTES_PER_COLOR

fileBitsBase := @byte[pBitmapFileInMemory][bfOffBits] ' get base of image in file (skip header)
pixColorAddr := @byte[fileBitsBase][nOffset] ' add in offset to 24-bit color
Expand Down
Loading

0 comments on commit f6c5421

Please sign in to comment.