Device: 16F1519 (enhanced mid-range) @ 4MHz for testing
Sensor: AS5048 rotary magnetic encoder
Language: MPASM
Simulation: MPLAB ICD3 SIM
SPI: 3-wire configuration (MOSI) tied high at sensor; TRIS=1 at MCU Master
I have SPI working with the following code:
I have gone a bit overboard with comments hoping that will help some readers avoid digging out the datasheet.
QUESTIONS:
1) I had been polling PIR1,SSPIF as my flag for SSPBUF full, but have switched to polling SSPSTAT,BF instead. Both seem to work. The latter avoids switching banks. So long as I am not using interrupts, is there any reason not to ignore SSPIF and just monitor BF?
2) SSPCON1,SSPM (ratio of SPI clock to Fosc): Fosc/4 and Fosc/16 work fine. Fosc/64 doesn't work in simulation . It hangs during polling. Any reason not to stay with Fosc/16?
3) Sequence of clearing CSn vs. setting SPEN? Doing either first works. Setting SPEN first seemed to make more sense, but clearing CSn first requires fewer bank changes. Nothing really seems to happen until SSPBUF is written.
4) SSPCON2,SEN : I am perplexed by what this does. I understand the description, but setting or clearing it doesn't seem to make a difference.This is the one question for which I am most clueless and worried. If it is not supposed to make a difference, why is it there for SPI? (I understand its use in slave mode.)
Sorry for the long question, most of it is code.
Thanks.
John
Sensor: AS5048 rotary magnetic encoder
Language: MPASM
Simulation: MPLAB ICD3 SIM
SPI: 3-wire configuration (MOSI) tied high at sensor; TRIS=1 at MCU Master
I have SPI working with the following code:
Code:
;TABS=5,GUTTER=4,WINDOW=80
#define SCK PORTC,3 ;slave clock, pin18
#define SDI PORTC,4 ;MISO, pin23
#define SDO PORTC,5 ;MOSI, pin24
#define CSn PORTA,5 ;!SS or chip select, pin7
#define LED LATD,0 ;output
;******************************************************************************
;SPI Testing
;******************************************************************************
;Seven registers in Bank 4 control the MSSP Modeule used with
;SPI and I2C communicaton. In addition TRIS(B2), LAT(B1), and PIR1,SSPIF(B0)
;are or may by used. The following applies only to SPI with the MCU as master:
;SSPSTAT: SMP<7>clear=sample at middle of output time
; CKE<6>set=transmit occurs on CLK active to idle,clear=idle to active
; <5,1> I2C read only
; BF<0>buffer full read only, set=receive complete
;SETTING: SSPSTAT=clear
;SSPCON1: WCOL<7>I2C only
; SSPOV<6>SSPBUF overflow error, not used in Master Mode
; SSPEN<5>enables serial port SCK,SDO, SDI and !SS(CSn)
; CKP<4>clock polarity,1=idle high, 0=idle low,see CKE above
; for AS5048 clock idle=low, send data on rising edge
; SSPM<3,0> 0010=M.clock=Fosc/64,0001=clock=Fosc/16,0000=clock=Fosc/4
;SETTING: SSPCON1=00?00010, <5>=SSPEN
;SSPCON2: <7,1> not used (SPI only)
; SEN<0>1=start condition on SDA and SCL pins,0=start condition idle
;SETTING: &&&&&&&&&&&&&&&&NOT SURE&&&&&&&&&&&&&&&
;SSPCON3: NOT USED (I2C)
;SSPMSK : NOT USED (I2C)
;SSPADD : NOT USED (Baud rate I2C)
;SSPBUF : Write ti initiate send, read on receipt
;
;PIR1,SSPIF:Flag for receipt...should SSPSTAT,BF be used instead?
;******************************************************************************
Test0 ;just a point to return to that shows an error
;setup serial port
MOVLB 4 ;SPI controls in Bank4 |B4
MOVLW b'00000001' ;
MOVWF SSPCON1 ;master clk=Fosc/16
;SSPCON1 <7,6> are read only, setting SSPEN<5> used to toggle SPI port on/off
;clearing<4> sets idle state for clock low, setting<3-0> low = master clk
;= Fosc/4, setting 0001 = master clk Fosc/16, <5> enables or resets SSP
;04.25.15 tried all 3 settings for <3,0>, Fosc/64 did not work, others did,
;hung up on waiting for the BF flag bit.
CLRF SSPCON2 ; |B4
BSF SSPCON2,SEN ;1=start condition on SDA aand SCL, 0=idle at start
CLRF SSPSTAT ; |B4
GetSPI
MOVLB 0 ; |B0
BCF CSn ; |B0
MOVLB 4 ; |B4
BSF SSPCON1,SSPEN ;enables serial port |B4
MOVLW 0xFF ;
MOVWF SSPBUF ; |B4
; CLRF SSPBUF ;also works to start
GetBUFF
;NB:Polling SSPSTAT,BF seems to work as well as polling PIR1,SSPIF and
;doesn't require bank switching.
btfss SSPSTAT,BF
goto $-1
movf SSPBUF,w
movwf SPI_H
CLRF SSPBUF
btfss SSPSTAT,BF
goto $-1
movf SSPBUF,w
movwf SPI_L
BCF SSPCON1,SSPEN ;disable SPI port
movlb 2 ; |B2
bsf LATA,5 ;set !SS(CSn)high
ErrTest
BTFSS SPI_H,7
GOTO Test0
BTFSC SPI_H,6
GOTO Test0
BCF SPI_H,7
; DelayCy (300*msecs)
; DelayCy (300*msecs)
goto Test0
QUESTIONS:
1) I had been polling PIR1,SSPIF as my flag for SSPBUF full, but have switched to polling SSPSTAT,BF instead. Both seem to work. The latter avoids switching banks. So long as I am not using interrupts, is there any reason not to ignore SSPIF and just monitor BF?
2) SSPCON1,SSPM (ratio of SPI clock to Fosc): Fosc/4 and Fosc/16 work fine. Fosc/64 doesn't work in simulation . It hangs during polling. Any reason not to stay with Fosc/16?
3) Sequence of clearing CSn vs. setting SPEN? Doing either first works. Setting SPEN first seemed to make more sense, but clearing CSn first requires fewer bank changes. Nothing really seems to happen until SSPBUF is written.
4) SSPCON2,SEN : I am perplexed by what this does. I understand the description, but setting or clearing it doesn't seem to make a difference.This is the one question for which I am most clueless and worried. If it is not supposed to make a difference, why is it there for SPI? (I understand its use in slave mode.)
Sorry for the long question, most of it is code.
Thanks.
John