I implemented hardware SPI using a PIC 16F877A and an ISD1740. I do it with ASM, but you can translate it to PICBasic if needed.
I'm posting it here because is the most extensive thread in the subject I could found, and I haven't found information about how to do it by hardware anywhere. I haven't finish yet, but I will probably forget to post it here late, so here goes what I've done so far.
As PIC SPI is Msb -> Lsb and ISD1700 is Lsb -> Msb, everything is inverted.
Code:
ISD commands:
;ISD led active on all the commands, for debugging, set bit 3 to 0 to disable ISD led flashing
CONSTANT SND_CMD_PU = b'10001000'
CONSTANT SND_CMD_SET_PLAY = b'00001001'
CONSTANT SND_CMD_SET_REC = b'10001001'
CONSTANT SND_CMD_PD = b'11101000'
CONSTANT SND_CMD_CLR_INT = b'00101000'
CONSTANT SND_CMD_WR_APC2 = b'10101110'
CONSTANT SND_CMD_WR_NVCFG = b'01101010'
CONSTANT SND_CMD_RD_STATUS = b'10101000'
;PIC ISD ports and pins
CONSTANT SND_PUERTO_ES = PORTC
CONSTANT SND_CONTROL_ES = TRISC
CONSTANT SND_PIN_E = .4
CONSTANT SND_PIN_S = .5
CONSTANT SND_PUERTO_CLK = PORTC
CONSTANT SND_CONTROL_CLK = TRISC
CONSTANT SND_PIN_CLK = .3
CONSTANT SND_PUERTO_SS = PORTA
CONSTANT SND_CONTROL_SS = TRISA
CONSTANT SND_PIN_SS = .5
;SPI configuration and activation
;PORTS config
banksel SND_CONTROL_ES
BCF SND_CONTROL_ES,SND_PIN_S
BSF SND_CONTROL_ES,SND_PIN_E
banksel SND_CONTROL_CLK
BCF SND_CONTROL_CLK,SND_PIN_CLK
banksel SND_PUERTO_ES
BCF SND_PUERTO_ES,SND_PIN_S
banksel SND_PUERTO_CLK
BSF SND_PUERTO_CLK,SND_PIN_CLK
;SPI config
banksel PIE1
BSF PIE1,SSPIE ;enable interrupt
banksel SSPSTAT
MOVLW b'00000000'
MOVWF SSPSTAT
;SSPM3:0 = 0001 = Fosc/16
banksel SSPCON
MOVLW b'00110001'
MOVWF SSPCON
;use SS to signal command start/stop
banksel SND_CONTROL_SS
BCF SND_CONTROL_SS,SND_PIN_SS
banksel SND_PUERTO_SS
BSF SND_PUERTO_SS,SND_PIN_SS
;SPI usage if not using interrupts
;active waiting for SPI transmission to end
snd_debug_esperar
banksel SSPSTAT
BTFSS SSPSTAT,BF
GOTO snd_debug_esperar
BCF SSPSTAT,BF
RETURN
;SPI without interrupts, to verify it works
snd_debug
;it has to be already configured, I'm ignoring ISD response
banksel SND_PUERTO_SS
BCF SND_PUERTO_SS,SND_PIN_SS ;start command
banksel SSPBUF
MOVLW SND_CMD_PU ;first byte
MOVWF SSPBUF
CALL snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
CLRW
MOVWF SSPBUF
call snd_debug_esperar
banksel SND_PUERTO_SS
BSF SND_PUERTO_SS,SND_PIN_SS
;enviar un SET_PLAY
pagesel snd_debug
banksel SND_PUERTO_SS
BCF SND_PUERTO_SS,SND_PIN_SS
MOVLW SND_CMD_SET_PLAY
banksel SSPBUF
MOVWF SSPBUF
CALL snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
CLRW
MOVWF SSPBUF
call snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
MOVLW b'0000100' ; 0x10 inverted
MOVWF SSPBUF
call snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
MOVLW 0x00
MOVWF SSPBUF
call snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
MOVLW b'0111111' ; 0x7E inverted
MOVWF SSPBUF
call snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
MOVLW 0x00
MOVWF SSPBUF
call snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
CLRW
MOVWF SSPBUF
call snd_debug_esperar
banksel SND_PUERTO_SS
BSF SND_PUERTO_SS,SND_PIN_SS
return
Sorry for the code format, I couldn't find a way to post it properly formatted.
DAvid
Bookmarks