' MAX7219_1.Bas (PICAXE-18X)
'
' Illustrates the use of a MAX7219 Serially Interfaced, 8-Digit
' Display Driver.
'
' Example uses four MAN74 7-Segment LEDs (Common Cathode) as Digits
' 3, 2, 1 and 0.  See Jameco #24782.
'
'  PICAXE-18X 	             MAX7219
'
'  CS (term 6) ------------ LOAD (term 12)
'  CLK (term 7) ----------- CLK (term 13)
'  DAT (term 8) ----------- DIN (term 1)
'
' In initializing the MAX7219;
'
'    Decode Mode (Register 9) set for Code B on all digits.
'    Intensity (Register 10) set for 17/32
'    Scan Limit (Register 11) set for Digits 0, 1, 2, 3
'    Shutdown (Register 12) set for normal operation.  (not shut down).
'
' The numbers 999 - 1035 are sequentially displayed.  No sign and no
' zero suppression.
'
' Uses nominally 300 bytes of program memory.
'
' This was a part of a Senior Project by Charne Owens.
'
' copyright, Charne Owens, Peter H Anderson, Baltimore, MD, April, '04


' define inputs and outputs
Symbol CS = 0	' out0
Symbol SCK = 1
Symbol MOSI = 2
Symbol MISO = Pin0	' input 0 (not used in this routine)

' define MAX7219 registers
Symbol DecodeMode = $09
Symbol Intensity = $0a
Symbol ScanLimit = 0x0b
Symbol Shutdown = $0c

' define variables
Symbol N = B0	' Used as Index in SPI_IO
Symbol X = B1	' value to be output in SPI_IO
Symbol Val = W1	' value to be displayed
Symbol VV = W2	' used in DisplayVal


Main:
   Pause 1000	' brief pause on boot to be sure MAX7219 is on

   Low SCK	' be sure SPI leads are properly set up
   Low MOSI
   High CS

   Pause 10

   GoSub SetUp	' set intensity, scan limit, decode mode, out of shutdown

Top:
   For Val = 999 to 1035
      GoSub BlankDisplay
      GoSub DisplayVal
      Pause 2000
   Next
   Goto Top


DisplayVal:	' display value

   VV = Val

   Low CS
   X = $04
   GoSub SPI_IO
   X = VV/1000		' get thousands
   GoSub SPI_IO
   High CS

   VV = VV % 1000

   Low CS
   X = $03
   GoSub SPI_IO
   X = VV/100		' hundreds
   GoSub SPI_IO
   High CS

   VV = VV % 100

   Low CS
   X = $02
   GoSub SPI_IO
   X = VV/10		' tens
   GoSub SPI_IO
   High CS

   VV = VV% 10

   Low CS
   X = $01
   GoSub SPI_IO
   X = VV		    ' units
   GoSub SPI_IO
   High CS

   Return

BlankDisplay:	' write $ff to each digit to blank

   Low CS
   X = $01
   GoSub SPI_IO
   X = $0f
   GoSub SPI_IO
   High CS

   Low CS
   X = $02
   GoSub SPI_IO
   X = $0f
   GoSub SPI_IO
   High CS

   Low CS
   X = $03
   GoSub SPI_IO
   X = $0f
   GoSub SPI_IO
   High CS

   Low CS
   X = $04
   GoSub SPI_IO
   X = $0f
   GoSub SPI_IO
   High CS


SetUp:

   Low CS
   X = DecodeMode
   GoSub SPI_IO
   X = $ff		' code B for all digits
   GoSub SPI_IO
   High CS

   Low CS
   X = ScanLimit
   GoSub SPI_IO
   X = $03		' display digits 1, 1, 2 and 3
   GoSub SPI_IO
   High CS

   Low CS
   X = Intensity
   GoSub SPI_IO
   X = $08		' 17 / 32 intensity
   GoSub SPI_IO
   High CS

   Low CS
   X = Shutdown
   GoSub SPI_IO
   X = $01		' normal operation - not shutdown
   GoSub SPI_IO
   High CS

   Return

SPI_IO:

   For N = 1 to 8
      If X > 127 Then SPI_IO_1	' if most sig bit is a one
      Low MOSI 			' otherwise set MOSI to a zero
      Goto SPI_IO_2

SPI_IO_1:
      High MOSI
SPI_IO_2:
      High SCK 				' clk high
      X = X * 2 + MISO			' read MISO
      Low SCK 				' clk low
   Next

   Return