Log in

View Full Version : SPI setup and AS1108 4 digit 7 segment decoder/driver



ecoli-557
- 5th November 2014, 15:11
Good Morning All-
I have been bumping my head against this problem for a few days and I wondered if someone might steer me in the correct direction.
I am trying to interface a AS1108 7 segment decoder driver to a 16F1527. I have stripped out all the other code normally used for debug like LEDs, etc.
I have read/re-read both the SPI section for the 16F1527, printed it, marked it up, almost used it for toilet paper <grin> and tried to make sense of how to set up the registers correctly.
Advice from other threads suggest using SHIFTOUT 1st to get it to work but the code listed looks as if it should work - but it doesn't.
I thought I would ask this venerable forum for any insights before I use the slower SHIFTOUT.
I have a logic analyzer (cheap) on the clock, data, and chip select pins and it looks like I am sending what I am supposed to so I think its in the timing, clock polarity, etc - but I can't seem to get it to work.
I'm certain it is a simple thing, I just am in the forest now........and no trees apparently!
I can't even get the 'H' to display!!! HELP!

Code below for reference:



'SPI code for 4 digit 7-segment display board
'The AS1108 contains four Digit-Registers and six control-registers. All registers are
'selected using a 4-bit address word, and communication is done via the serial interface.
'DIGIT Registers – These registers are realized with an on-chip 32-bit memory. Each digit can be controlled directly
'without rewriting the whole register contents.
'CONTROL Registers – These registers consist of decode mode, display intensity, number of scanned digits, shutdown,
'display test and features selection registers.
'Set for using PIC16F1527
'Programmed using PicBasic Pro 3.0.1.4
'Environment MCSP 5.0.0.2
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _WRT_OFF & _STVREN_ON & _LVP_OFF
#ENDCONFIG

'-----------------------------------------------------------------------------------------------------------------------
'Define the oscillator and setup the INCLUDE files
DEFINE OSC 20 '20 MHz oscillator, however, use the internal for now

'OKAY, Lets set up the registers.....
OSCCON=%01111010 '16 MHz internal clock
ANSELA=%00000111 'Sets the 1st 3 bits as analog
ANSELB=0 'Sets IO to DIGITAL
ANSELD=0 'Sets IO to DIGITAL
ANSELE=0 'Sets IO to DIGITAL
ANSELF=0 'Sets IO to DIGITAL
ANSELG=0 'Sets IO to DIGITAL
WPUB= %00000000 'DISABLES weak pullups on PORTB
WPUD= %11111111 'ENABLES weak pullups on PORTD
WPUE= %11111111 'ENABLES weak pullups on PORTE
FVRCON=%11000011 'Voltage Ref is ENABLED at 4.096 volts
ADCON0=%00000001 'Turns ON ADC, PORT A
ADCON1=%11010011 'Right justifies, Fosc/16, Vref is connected to FVR internal
CCP1CON=%00000000 'Turns OFF capture, compare, pwm
CCP2CON=%00000000 'Turns OFF capture, compare, pwm
CCP3CON=%00000000 'Turns OFF capture, compare, pwm
CCP4CON=%00000000 'Turns OFF capture, compare, pwm
CCP5CON=%00000000 'Turns OFF capture, compare, pwm
CCP6CON=%00000000 'Turns OFF capture, compare, pwm
CCP7CON=%00000000 'Turns OFF capture, compare, pwm
CCP8CON=%00000000 'Turns OFF capture, compare, pwm
CCP9CON=%00000000 'Turns OFF capture, compare, pwm
CCP10CON=%00000000 'Turns OFF capture, compare, pwm
OPTION_REG=%01000111 'TMR0 enabled, use internal (Fosc/4) Clock
'Low to High transition, use prescaler of 1:64
'-----------------------------------------------------------------------------------------------------------------------
'Direction registers
TRISA = %10000111 'Set PORTA for bit7 is clk in, 4 led out, 3 A/D in
TRISB = %11000000 'PORTB is OUTPUT, except B6&B7
TRISC = %10010000 'Set RC7 (RX), SDI, rest are outputs
TRISD = %11111111 'Set PORTD for high order INPUTS
TRISE = %11111111 'Set PORTE for low order INPUTS
TRISF = %00000000 'PORTF is low order OUTPUT
TRISG = %00100110 'PORTG is mixed
'-----------------------------------------------------------------------------------------------------------------------
WPUG.5=1 'Weak pullup in on MCLR
'-----------------------------------------------------------------------------------------------------------------------
'****Here is my SPI Setup****
'The AS1108 is selected by CS going low, after 16 clock cycles, shifted in when CS goes back high
SSP1STAT.7 = 1 'SMP=0, sample phase
SSP1STAT.6 = 1 'CKE=1, xmits on rising edge
SSP1CON1.5=1 'enable SPI
SSP1CON1.4=0 'CKP=0, clk idles low
SSPCON.3=0 'bit 3 to 0 indicate clock speed. bit 0 set means clock = OSC/16 = 1.25 MHz @ 20MHz
SSPCON.2=0
SSPCON.1=0
SSPCON.0=1
PIR1.3 = 0 'Clear the buffer status.

'-----------------------------------------------------------------------------------------------------------------------
'Additional I/O Definitions
as1108sel var PORTC.2


'-----------------------------------------------------------------------------------------------------------------------
'Vars
SPIin VAR WORD 'DATA back from device
SPIout VAR WORD 'DATA to the device


'-----------------------------------------------------------------------------------------------------------------------
'AS1108 Data Frame structor
'D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
'X X X X Register Address MSB------Data--------LSB
'-----------------------------------------------------------

'Register Address
' Register Address Map
'Register HEX Code Address
' D15:D12 D11 D10 D9 D8
'No-Op 0xX0 X 0 0 0 0
'Digit 0 0xX1 X 0 0 0 1
'Digit 1 0xX2 X 0 0 1 0
'Digit 2 0xX3 X 0 0 1 1
'Digit 3 0xX4 X 0 1 0 0
'Decode-Mode 0xX9 X 1 0 0 1
'Intensity Control 0xXA X 1 0 1 0
'Scan Limit 0xXB X 1 0 1 1
'Shutdown 0xXC X 1 1 0 0
'N/A 0xXD X 1 1 0 1
'Feature 0xXE X 1 1 1 0
'Display Test 0xXF X 1 1 1 1


No_Op con $00 'not used for 1 Chip AS1108
Digit_1 con $01
Digit_2 con $02
Digit_3 con $03
Digit_4 con $04
Decode_Mode con $09
Intensity_Control con $0A
Scan_Limit con $0B
Shutdown con $0C
N_A con $0D
Feature con $0E
Display_Test con $0F



'Decode Enable Register (0xX9)
'The Decode Enable Register sets the decode mode. BCD/HEX decoding (either BCD code – characters 0:9, E, H, L,
'P, and -, or HEX code – characters 0:9 and A:F) is selected by bit D2 of the Feature Register. The Decode
'Enable Register is used to select the decode mode or no-decode for each digit. Each bit in the Decode Enable Register
'corresponds to its respective display digit (i.e., bit D0 corresponds to digit 0, bit D1 corresponds to digit 1 and so
'on).

'Note: A logic high enables decoding and a logic low bypasses the decoder altogether.

'When decode mode is used, the decoder looks only at the lower-nibble (bits D3:D0) of the data in the Digit-Registers,
'disregarding bits D6:D4. Bit D7 sets the decimal point (SEG DP) independent of the decoder and is positive logic (bit
'D7 = 1 turns the decimal point on).
'When no-decode mode is selected, data bits D7:D0 of the Digit-Registers correspond to the segment lines of the
'AS1108.

'Decode Mode HEX Code Register Data
' D7 D6 D5 D4 D3 D2 D1 D0
'No decode for digits 3:0 0x00 X X X X 0 0 0 0
'Code-B/HEX decode for digit 0. No decode for digits 3:1 0x01 X X X X 0 0 0 1
'Code-B/HEX decode for digits 3:0 0xFF X X X X 1 1 1 1

' Code-B Font
'7-Segment Register Data On Segments = 1
' D7 D6:D4 D3 D2 D1 D0 DP A B C D E F G
' 0 X 0 0 0 0 1 1 1 1 1 1 0
' 1 X 0 0 0 1 0 1 1 0 0 0 0
' 2 X 0 0 1 0 1 1 0 1 1 0 1
' 3 X 0 0 1 1 1 1 1 1 0 0 1
' 4 X 0 1 0 0 0 1 1 0 0 1 1
' 5 X 0 1 0 1 1 0 1 1 0 1 1
' 6 X 0 1 1 0 1 0 1 1 1 1 1
' 7 X 0 1 1 1 1 1 1 0 0 0 0
' 8 X 1 0 0 0 1 1 1 1 1 1 1
' 9 X 1 0 0 1 1 1 1 1 0 1 1
' - X 1 0 1 0 0 0 0 0 0 0 1
' E X 1 0 1 1 1 0 0 1 1 1 1
' H X 1 1 0 0 0 1 1 0 1 1 1
' L X 1 1 0 1 0 0 0 1 1 1 0
' P X 1 1 1 0 1 1 0 0 1 1 1
'Blank X 1 1 1 1 0 0 0 0 0 0 0
' The decimal point is enabled by setting bit D7 = 1.

' HEX Font
'7-Segment Register Data On Segments = 1
' D7 D6:D4 D3 D2 D1 D0 DP A B C D E F G
' 0 X 0 0 0 0 1 1 1 1 1 1 0
' 1 X 0 0 0 1 0 1 1 0 0 0 0
' 2 X 0 0 1 0 1 1 0 1 1 0 1
' 3 X 0 0 1 1 1 1 1 1 0 0 1
' 4 X 0 1 0 0 0 1 1 0 0 1 1
' 5 X 0 1 0 1 1 0 1 1 0 1 1
' 6 X 0 1 1 0 1 0 1 1 1 1 1
' 7 X 0 1 1 1 1 1 1 0 0 0 0
' 8 X 1 0 0 0 1 1 1 1 1 1 1
' 9 X 1 0 0 1 1 1 1 1 0 1 1
' A X 1 0 1 0 1 1 1 0 1 1 1
' b X 1 0 1 1 0 0 1 1 1 1 1
' C X 1 1 0 0 1 0 0 1 1 1 0
' d X 1 1 0 1 0 1 1 1 1 0 1
' E X 1 1 1 0 1 0 0 1 1 1 1
' F X 1 1 1 1 1 0 0 0 1 1 1
' The decimal point is enabled by setting bit D7 = 1.


'Decode_Mode (0x09)
decode_mode_1 con 00 'No decode for digits 3:0
decode_mode_2 con 01 'Code-B/HEX decode for digit 0. No decode for digits 3:1
decode_mode_3 con $FF 'Code-B/HEX decode for digits 3:0

'Display-Test Register (0xXF)
'The AS1108 can operate in two modes: normal mode and display test mode. In display test mode all LEDs are
'switched on at maximum brightness (duty cycle is 15/16). The device remains in display-test mode until the Display-
'Test Register is set for normal operation.

'Display_Test (0x0F)
display_test_mode_1 con 00 'Normal Operation
display_test_mode_2 con 01 'Display Test Mode


'Intensity Control Register (0xXA)
'The brightness of the display can be controlled by digital means using the Intensity Control Register and by analog
'means using RSET.
'Display brightness is controlled by an integrated pulse-width modulator which is controlled by the lower-nibble of the
'Intensity Control Register. The modulator scales the average segment-current in 16 steps from a maximum of 31/32
'down to 1/32 of the peak current set by RSET.

'Intensity Control Register (0x0A) have 16 Level brightness
intensity_level_0 con 00 '1/32 (min on) 0xX0
intensity_level_1 con 01 '3/32 0xX1
intensity_level_2 con 02 '5/32 0xX2
intensity_level_3 con 03 '7/32 0xX3
intensity_level_4 con 04 '9/32 0xX4
intensity_level_5 con 05 '11/32 0xX5
intensity_level_6 con 06 '13/32 0xX6
intensity_level_7 con 07 '15/32 0xX7
intensity_level_8 con 08 '17/32 0xX8
intensity_level_9 con 09 '19/32 0xX9
intensity_level_10 con $0A '21/32 0xXA
intensity_level_11 con $0B '23/32 0xXB
intensity_level_12 con $0C '25/32 0xXC
intensity_level_13 con $0D '27/32 0xXD
intensity_level_14 con $0E '29/32 0xXE
intensity_level_15 con $0F '31/32 (max on) 0xXF

'Scan-Limit Register (0x0B)
'The Scan-Limit Register controls which of the digits are to be displayed. When all 4 digits are to be displayed, the
'update frequency is typically 1600Hz. If the number of digits displayed is reduced, the update frequency is increased.
'The frequency can be calculated using 8fOSC/N, where N is the number of digits. Since the number of displayed digits
'influences the brightness, RSET should be adjusted accordingly.
'Note: To avoid differences in brightness this register should not be used to blank parts of the display (leading zeros).

'Scan-Limit Register (0x0B)

Scan_Limit_mode_1 con 00 'Display digit 0 only
Scan_Limit_mode_2 con 01 'Display digits 0:1
Scan_Limit_mode_3 con 02 'Display digits 0:2
Scan_Limit_mode_4 con 03 'Display digits 0:3

'Feature Register (0xXE)
'The Feature Register is used for switching the device into external clock mode, applying an external reset, selecting
'code-B or HEX decoding, enabling or disabling blinking, enabling or disabling the SPI-compatible interface, setting the
'blinking rate, and resetting the blink timing.

'Feature Register Summary
'D7 D6 D5 D4 D3 D2 D1 D0
'blink_ sync blink_ Blink_ spi_en decode_sel reg_res clk_en
'start freq_sel en


'Bit Bit Name Default Access Bit Description
'D0 clk_en 0 R/W External clock select.
' 0 = Internal oscillator is used for system clock.
' 1 = Pin CLK of the serial interface operates as system clock input.
'D1 reg_res 0 R/W Resets all control registers except the Feature Register.
' 0 = Reset Disabled. Normal operation.
' 1 = All control registers are reset to default state (except the Feature
' Register) identically after power-up.
' Note: The Digit Registers maintain their data.
'D2 decode_sel 0 R/W Selects display decoding.
' 0 = Enable Code-B decoding
' 1 = Enable HEX decoding
'D3 spi_en 0 R/W Enables the SPI-compatible interface.
' 0 = Disable SPI-compatible interface.
' 1 = Enable the SPI-compatible interface.
'D4 blink_en 0 R/W Enables blinking.
' 0 = Disable blinking.
' 1 = Enable blinking.
'D5 blink_freq_sel 0 R/W Sets blink with low frequency (with the internal oscillator enabled):
' 0 = Blink period typically is 1 second (0.5s on, 0.5s off).
' 1 = Blink period is 2 seconds (1s on, 1s off).
'D6 sync 0 R/W Synchronizes blinking on the rising edge of pin LOAD/CSN. The
' multiplex and blink timing counter is cleared on the rising edge of pin
' LOAD/CSN. By setting this bit in multiple AS1108 devices, the blink
' timing can be synchronized across all the devices.
'D7 blink_start 0 R/W Start Blinking with display enabled phase. When bit D4 (blink_en) is set,
' bit D7 determines how blinking starts.
' 0 = Blinking starts with the display turned off.
' 1 = Blinking starts with the display turned on.

SysFeature con %00001101 'HEX decoding and external clock is clock-in

'Setup to actually start writing to display controller
' Use Code-B, Normal operation w/ feature reg unchanged, Normal operation, Code-B hex for digits 3:0, Max intensity, display all 4 digits.

goto init 'Jumps around subs

'-----------------------------------------------------------------------------------------------------------------------
'Subs
'**********SPI SEND******************
Send_SPIData:
as1108sel=0 'Select the chip
SSP1BUF = SPIout.HIGHBYTE
while !PIR1.3 : wend
' pauseus 1
PIR1.3=0 'Reset the flag
SSP1CON1.7=0 'Clear collision bit
SSP1BUF = SPIout.LOWByte
while !PIR1.3 : wend
' pauseus 1
PIR1.3 = 0 'Reset the flag
SSP1CON1.7=0 'Clear collision bit
as1108sel=1 'Deselect the chip
return

'-----------------------------------------------------------------------------------------------------------------------


init:
AS1108SEL=1
SSP1CON1.7=0 'Clear collision bit
PIR1.3=0 'Reset the flag

'Sets up the 4 digit display
SPIout.highbyte=feature
SPIout.lowbyte=sysfeature 'Sets up the feature register
gosub Send_SPIData
' pauseus 2
spiout.highbyte=Scan_Limit
SPIout.lowbyte=Scan_Limit_mode_4 'Uses all 4 digits
gosub Send_SPIData
' pauseus 2
spiout.highbyte=Intensity_Control
SPIout.lowbyte=intensity_level_11 'Intensity set to 11
gosub Send_SPIData
' pauseus 2
spiout.highbyte=Decode_Mode
SPIout.lowbyte=Decode_Mode_3 'Hex decode for all 4 difits
gosub Send_SPIData
' pauseus 2
'Disply HELP as a signon.....
spiout.highbyte=Digit_4
SPIout.lowbyte=$C 'Disp 'H'
gosub Send_SPIData
' pauseus 2
' spiout.highbyte=Digit_3
' SPIout.lowbyte=$B 'Disp 'E'
' gosub Send_SPIData
' pauseus 2
' spiout.highbyte=Digit_2
' SPIout.lowbyte=$D 'Disp 'L'
' gosub Send_SPIData
' pauseus 2
' spiout.highbyte=Digit_1
' SPIout.lowbyte=$E 'Disp 'P'
' gosub Send_SPIData
' pauseus 2

stop 'See if it works......

towlerg
- 5th November 2014, 20:03
I think you have CKE wrong, you've set clock to idle low so you want CKE = 0 "Transmit occurs on transition from Idle to active clock state".

George

ecoli-557
- 5th November 2014, 20:33
Thanks George, I'm pretty sure I have tried that but I will look at that once again.
I just now had a thought about the clock, I may be misguided in what the sheet says it really does.........
Still hangin' in here......
I'll chase another rabbit and see where it leads......

towlerg
- 5th November 2014, 22:01
Not wishing to labor the point but (ah, there's always a but) looking at this diagram from the datasheet

Clock is idle low and data is clocked by idle to active clock. Sample (assuming you're reading as well) seems to be either but I guess preferably middle.

George

JIC use your analyzer to ensure that you're sending 16 bits between CSN low and CSN high

ecoli-557
- 6th November 2014, 15:11
I found the problem!
Stupid me, I 'thought' the clock in the FEATURE reg was to clock the entire system, well, it turns out it uses 2 clocks apparently. System clock to clock data in, then an internal clock to actually clock into the internal registers.
Also, upon carefully re-reading the data (with an Adult Beverage) I found that the chip has to be told to come out of SHUTDOWN, well the working code is below for others to use.

You CAN use the MSSI for SPI, as has been said before, you do have to be careful and read the manual apparently 23 times <grin>.
George- The chip works with SMP=0, CKE=1, CKP=0

Working code below:


'SPI code for 4 digit 7-segment display board
'The AS1108 contains four Digit-Registers and six control-registers. All registers are
'selected using a 4-bit address word, and communication is done via the serial interface.
'DIGIT Registers – These registers are realized with an on-chip 32-bit memory. Each digit can be controlled directly
'without rewriting the whole register contents.
'CONTROL Registers – These registers consist of decode mode, display intensity, number of scanned digits, shutdown,
'display test and features selection registers.
'Set for using PIC16F1527
'Programmed using PicBasic Pro 3.0.1.4
'Environment MCSP 5.0.0.2
#CONFIG
__config _CONFIG1, _FOSC_ECH & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _WRT_OFF & _STVREN_ON & _LVP_OFF
#ENDCONFIG

'-----------------------------------------------------------------------------------------------------------------------
'Define the oscillator and setup the INCLUDE files
DEFINE OSC 20 '20 MHz oscillator

'OKAY, Lets set up the registers.....
OSCCON=%01111010 '16 MHz internal clock
ANSELA=%00000111 'Sets the 1st 3 bits as analog
ANSELB=0 'Sets IO to DIGITAL
ANSELD=0 'Sets IO to DIGITAL
ANSELE=0 'Sets IO to DIGITAL
ANSELF=0 'Sets IO to DIGITAL
ANSELG=0 'Sets IO to DIGITAL
WPUB= %00000000 'DISABLES weak pullups on PORTB
WPUD= %11111111 'ENABLES weak pullups on PORTD
WPUE= %11111111 'ENABLES weak pullups on PORTE
FVRCON=%11000011 'Voltage Ref is ENABLED at 4.096 volts
ADCON0=%00000001 'Turns ON ADC, PORT A
ADCON1=%11010011 'Right justifies, Fosc/16, Vref is connected to FVR internal
CCP1CON=%00000000 'Turns OFF capture, compare, pwm
CCP2CON=%00000000 'Turns OFF capture, compare, pwm
CCP3CON=%00000000 'Turns OFF capture, compare, pwm
CCP4CON=%00000000 'Turns OFF capture, compare, pwm
CCP5CON=%00000000 'Turns OFF capture, compare, pwm
CCP6CON=%00000000 'Turns OFF capture, compare, pwm
CCP7CON=%00000000 'Turns OFF capture, compare, pwm
CCP8CON=%00000000 'Turns OFF capture, compare, pwm
CCP9CON=%00000000 'Turns OFF capture, compare, pwm
CCP10CON=%00000000 'Turns OFF capture, compare, pwm
OPTION_REG=%01000111 'TMR0 enabled, use internal (Fosc/4) Clock
'Low to High transition, use prescaler of 1:64
'-----------------------------------------------------------------------------------------------------------------------
'Direction registers
TRISA = %10000111 'Set PORTA for bit7 is clk in, 4 led out, 3 A/D in
TRISB = %11000000 'PORTB is OUTPUT, except B6&B7
TRISC = %10010000 'Set RC7 (RX), SDI, rest are outputs
TRISD = %11111111 'Set PORTD for high order INPUTS
TRISE = %11111111 'Set PORTE for low order INPUTS
TRISF = %00000000 'PORTF is low order OUTPUT
TRISG = %00100110 'PORTG is mixed
'-----------------------------------------------------------------------------------------------------------------------
WPUG.5=1 'Weak pullup in on MCLR
'-----------------------------------------------------------------------------------------------------------------------
'****Here is my SPI Setup****
'The AS1108 is selected by CS going low, after 16 clock cycles, shifted in when CS goes back high
SSP1STAT.7 = 0 'SMP=0, sample phase
SSP1STAT.6 = 1 'CKE=1, xmits on rising edge
SSP1CON1.5=1 'enable SPI
SSP1CON1.4=0 'CKP=0, clk idles low
SSPCON.3=0 'bit 3 to 0 indicate clock speed. bit 0 set means clock = OSC/16 = 1.25 MHz @ 20MHz
SSPCON.2=0
SSPCON.1=0
SSPCON.0=1
PIR1.3 = 0 'Clear the buffer status.
'Found this to help out w/ low 4 bits of SSPCON:
'0000 = SPI Master mode, clock Fosc/4
'0001 = SPI Master mode, clock = Fosc/16
'0010 = SPI Master mode, clock = Fosc/64
'0011 = SPI Master mode, clock = TMR2 output/2
'0100 = SPI Slave mode, clock = SCK pin. SS pin control enabled
'0101 = SPI Slave mode, clock = SCK pin. SS pin control disabled. SS can be used as I/O pin.
'0110 = I2C Slave mode, 7-bit address
'0111 = I2C Slave mode, 10-bit address
'1011 = I2C Firmware Controlled Master mode (slave IDLE)
'1110 = I2C Slave mode, 7-bit address with START and STOP bit interrupts enabled
'1111 = I2C Slave mode, 10-bit address with START and STOP bit interrupts enabled
'-----------------------------------------------------------------------------------------------------------------------
'Additional I/O Definitions
as1108sel var PORTC.2


'-----------------------------------------------------------------------------------------------------------------------
'Vars
SPIin VAR WORD 'DATA back from device
SPIout VAR WORD 'DATA to the device


'-----------------------------------------------------------------------------------------------------------------------
'AS1108 Data Frame structor
'D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
'X X X X Register Address MSB------Data--------LSB
'-----------------------------------------------------------

'Register Address
' Register Address Map
'Register HEX Code Address
' D15:D12 D11 D10 D9 D8
'No-Op 0xX0 X 0 0 0 0
'Digit 0 0xX1 X 0 0 0 1
'Digit 1 0xX2 X 0 0 1 0
'Digit 2 0xX3 X 0 0 1 1
'Digit 3 0xX4 X 0 1 0 0
'Decode-Mode 0xX9 X 1 0 0 1
'Intensity Control 0xXA X 1 0 1 0
'Scan Limit 0xXB X 1 0 1 1
'Shutdown 0xXC X 1 1 0 0
'N/A 0xXD X 1 1 0 1
'Feature 0xXE X 1 1 1 0
'Display Test 0xXF X 1 1 1 1


No_Op con $00 'not used for 1 Chip AS1108
Digit_1 con $01
Digit_2 con $02
Digit_3 con $03
Digit_4 con $04
Decode_Mode con $09
Intensity_Control con $0A
Scan_Limit con $0B
Shutdown con $0C
N_A con $0D
Feature con $0E
Display_Test con $0F



'Decode Enable Register (0xX9)
'The Decode Enable Register sets the decode mode. BCD/HEX decoding (either BCD code – characters 0:9, E, H, L,
'P, and -, or HEX code – characters 0:9 and A:F) is selected by bit D2 of the Feature Register. The Decode
'Enable Register is used to select the decode mode or no-decode for each digit. Each bit in the Decode Enable Register
'corresponds to its respective display digit (i.e., bit D0 corresponds to digit 0, bit D1 corresponds to digit 1 and so
'on).

'Note: A logic high enables decoding and a logic low bypasses the decoder altogether.

'When decode mode is used, the decoder looks only at the lower-nibble (bits D3:D0) of the data in the Digit-Registers,
'disregarding bits D6:D4. Bit D7 sets the decimal point (SEG DP) independent of the decoder and is positive logic (bit
'D7 = 1 turns the decimal point on).
'When no-decode mode is selected, data bits D7:D0 of the Digit-Registers correspond to the segment lines of the
'AS1108.

'Decode Mode HEX Code Register Data
' D7 D6 D5 D4 D3 D2 D1 D0
'No decode for digits 3:0 0x00 X X X X 0 0 0 0
'Code-B/HEX decode for digit 0. No decode for digits 3:1 0x01 X X X X 0 0 0 1
'Code-B/HEX decode for digits 3:0 0xFF X X X X 1 1 1 1

' Code-B Font
'7-Segment Register Data On Segments = 1
' D7 D6:D4 D3 D2 D1 D0 DP A B C D E F G
' 0 X 0 0 0 0 1 1 1 1 1 1 0
' 1 X 0 0 0 1 0 1 1 0 0 0 0
' 2 X 0 0 1 0 1 1 0 1 1 0 1
' 3 X 0 0 1 1 1 1 1 1 0 0 1
' 4 X 0 1 0 0 0 1 1 0 0 1 1
' 5 X 0 1 0 1 1 0 1 1 0 1 1
' 6 X 0 1 1 0 1 0 1 1 1 1 1
' 7 X 0 1 1 1 1 1 1 0 0 0 0
' 8 X 1 0 0 0 1 1 1 1 1 1 1
' 9 X 1 0 0 1 1 1 1 1 0 1 1
' - X 1 0 1 0 0 0 0 0 0 0 1
' E X 1 0 1 1 1 0 0 1 1 1 1
' H X 1 1 0 0 0 1 1 0 1 1 1
' L X 1 1 0 1 0 0 0 1 1 1 0
' P X 1 1 1 0 1 1 0 0 1 1 1
'Blank X 1 1 1 1 0 0 0 0 0 0 0
' The decimal point is enabled by setting bit D7 = 1.

' HEX Font
'7-Segment Register Data On Segments = 1
' D7 D6:D4 D3 D2 D1 D0 DP A B C D E F G
' 0 X 0 0 0 0 1 1 1 1 1 1 0
' 1 X 0 0 0 1 0 1 1 0 0 0 0
' 2 X 0 0 1 0 1 1 0 1 1 0 1
' 3 X 0 0 1 1 1 1 1 1 0 0 1
' 4 X 0 1 0 0 0 1 1 0 0 1 1
' 5 X 0 1 0 1 1 0 1 1 0 1 1
' 6 X 0 1 1 0 1 0 1 1 1 1 1
' 7 X 0 1 1 1 1 1 1 0 0 0 0
' 8 X 1 0 0 0 1 1 1 1 1 1 1
' 9 X 1 0 0 1 1 1 1 1 0 1 1
' A X 1 0 1 0 1 1 1 0 1 1 1
' b X 1 0 1 1 0 0 1 1 1 1 1
' C X 1 1 0 0 1 0 0 1 1 1 0
' d X 1 1 0 1 0 1 1 1 1 0 1
' E X 1 1 1 0 1 0 0 1 1 1 1
' F X 1 1 1 1 1 0 0 0 1 1 1
' The decimal point is enabled by setting bit D7 = 1.


'Decode_Mode (0x09)
decode_mode_1 con 00 'No decode for digits 3:0
decode_mode_2 con 01 'Code-B/HEX decode for digit 0. No decode for digits 3:1
decode_mode_3 con $FF 'Code-B/HEX decode for digits 3:0

'Display-Test Register (0xXF)
'The AS1108 can operate in two modes: normal mode and display test mode. In display test mode all LEDs are
'switched on at maximum brightness (duty cycle is 15/16). The device remains in display-test mode until the Display-
'Test Register is set for normal operation.

'Display_Test (0x0F)
display_test_mode_1 con 00 'Normal Operation
display_test_mode_2 con 01 'Display Test Mode


'Intensity Control Register (0xXA)
'The brightness of the display can be controlled by digital means using the Intensity Control Register and by analog
'means using RSET.
'Display brightness is controlled by an integrated pulse-width modulator which is controlled by the lower-nibble of the
'Intensity Control Register. The modulator scales the average segment-current in 16 steps from a maximum of 31/32
'down to 1/32 of the peak current set by RSET.

'Intensity Control Register (0x0A) have 16 Level brightness
intensity_level_0 con 00 '1/32 (min on) 0xX0
intensity_level_1 con 01 '3/32 0xX1
intensity_level_2 con 02 '5/32 0xX2
intensity_level_3 con 03 '7/32 0xX3
intensity_level_4 con 04 '9/32 0xX4
intensity_level_5 con 05 '11/32 0xX5
intensity_level_6 con 06 '13/32 0xX6
intensity_level_7 con 07 '15/32 0xX7
intensity_level_8 con 08 '17/32 0xX8
intensity_level_9 con 09 '19/32 0xX9
intensity_level_10 con $0A '21/32 0xXA
intensity_level_11 con $0B '23/32 0xXB
intensity_level_12 con $0C '25/32 0xXC
intensity_level_13 con $0D '27/32 0xXD
intensity_level_14 con $0E '29/32 0xXE
intensity_level_15 con $0F '31/32 (max on) 0xXF

'Scan-Limit Register (0x0B)
'The Scan-Limit Register controls which of the digits are to be displayed. When all 4 digits are to be displayed, the
'update frequency is typically 1600Hz. If the number of digits displayed is reduced, the update frequency is increased.
'The frequency can be calculated using 8fOSC/N, where N is the number of digits. Since the number of displayed digits
'influences the brightness, RSET should be adjusted accordingly.
'Note: To avoid differences in brightness this register should not be used to blank parts of the display (leading zeros).

'Scan-Limit Register (0x0B)

Scan_Limit_mode_1 con 00 'Display digit 0 only
Scan_Limit_mode_2 con 01 'Display digits 0:1
Scan_Limit_mode_3 con 02 'Display digits 0:2
Scan_Limit_mode_4 con 03 'Display digits 0:3

'Feature Register (0xXE)
'The Feature Register is used for switching the device into external clock mode, applying an external reset, selecting
'code-B or HEX decoding, enabling or disabling blinking, enabling or disabling the SPI-compatible interface, setting the
'blinking rate, and resetting the blink timing.

'Feature Register Summary
'D7 D6 D5 D4 D3 D2 D1 D0
'blink_ sync blink_ Blink_ spi_en decode_sel reg_res clk_en
'start freq_sel en


'Bit Bit Name Default Access Bit Description
'D0 clk_en 0 R/W External clock select.
' 0 = Internal oscillator is used for system clock.
' 1 = Pin CLK of the serial interface operates as system clock input.
'D1 reg_res 0 R/W Resets all control registers except the Feature Register.
' 0 = Reset Disabled. Normal operation.
' 1 = All control registers are reset to default state (except the Feature
' Register) identically after power-up.
' Note: The Digit Registers maintain their data.
'D2 decode_sel 0 R/W Selects display decoding.
' 0 = Enable Code-B decoding
' 1 = Enable HEX decoding
'D3 spi_en 0 R/W Enables the SPI-compatible interface.
' 0 = Disable SPI-compatible interface.
' 1 = Enable the SPI-compatible interface.
'D4 blink_en 0 R/W Enables blinking.
' 0 = Disable blinking.
' 1 = Enable blinking.
'D5 blink_freq_sel 0 R/W Sets blink with low frequency (with the internal oscillator enabled):
' 0 = Blink period typically is 1 second (0.5s on, 0.5s off).
' 1 = Blink period is 2 seconds (1s on, 1s off).
'D6 sync 0 R/W Synchronizes blinking on the rising edge of pin LOAD/CSN. The
' multiplex and blink timing counter is cleared on the rising edge of pin
' LOAD/CSN. By setting this bit in multiple AS1108 devices, the blink
' timing can be synchronized across all the devices.
'D7 blink_start 0 R/W Start Blinking with display enabled phase. When bit D4 (blink_en) is set,
' bit D7 determines how blinking starts.
' 0 = Blinking starts with the display turned off.
' 1 = Blinking starts with the display turned on.

SysFeature con %00001000 'Code-B decoding and internal clock (this was the big deal, INTERNAL CLOCK!)

'Setup to actually start writing to display controller
' Use Code-B, Normal operation w/ feature reg unchanged, Normal operation, Code-B hex for digits 3:0, Max intensity, display all 4 digits.

goto init 'Jumps around subs

'-----------------------------------------------------------------------------------------------------------------------
'Subs
'**********SPI SEND******************
Send_SPIData:
as1108sel=0 'Select the chip
SSP1BUF = SPIout.HIGHBYTE
while !PIR1.3 : wend
' pauseus 1
PIR1.3=0 'Reset the flag
SSP1CON1.7=0 'Clear collision bit
SSP1BUF = SPIout.LOWByte
while !PIR1.3 : wend
' pauseus 1
PIR1.3 = 0 'Reset the flag
SSP1CON1.7=0 'Clear collision bit
as1108sel=1 'Deselect the chip
return

'-----------------------------------------------------------------------------------------------------------------------


init:
AS1108SEL=1
SSP1CON1.7=0 'Clear collision bit
PIR1.3=0 'Reset the flag

'Sets up the 4 digit display
SPIout.highbyte=Shutdown
SPIout.lowbyte=$01 'Sets up normal op out of shutdown
gosub Send_SPIData
' pauseus 2
SPIout.highbyte=feature
SPIout.lowbyte=sysfeature 'Sets up the feature register
gosub Send_SPIData
' pauseus 2
spiout.highbyte=Scan_Limit
SPIout.lowbyte=$03 'Uses all 4 digits
gosub Send_SPIData
' pauseus 2
spiout.highbyte=Intensity_Control
SPIout.lowbyte=intensity_level_15 'Intensity set to 15, highest
gosub Send_SPIData
' pauseus 2
spiout.highbyte=Decode_Mode
SPIout.lowbyte=Decode_Mode_3 'Hex decode for all 4 difits
gosub Send_SPIData
' pauseus 2
spiout.highbyte=Display_Test
SPIout.lowbyte=display_test_mode_1 'Normal operation
gosub Send_SPIData
' pauseus 2
'Disply HELP as a signon.....
spiout.highbyte=Digit_1
SPIout.lowbyte=$0C 'Disp 'H'
gosub Send_SPIData
' pauseus 2
spiout.highbyte=Digit_2
SPIout.lowbyte=$0B 'Disp 'E'
gosub Send_SPIData
' pauseus 2
spiout.highbyte=Digit_3
SPIout.lowbyte=$0D 'Disp 'L'
gosub Send_SPIData
' pauseus 2
spiout.highbyte=Digit_4
SPIout.lowbyte=$0E 'Disp 'P'
gosub Send_SPIData
' pauseus 2

stop 'See if it works......It's ALIVE!