/* spi.c */ #include "spi.h" #include "interrupt.h" #include "event.h" #include "uart.h" #define SSPBASE 0xE0068000 #define SSPCR0 0x00 #define SSPCR1 0x04 #define SSPDR 0x08 #define SSPSR 0x0c #define SSPCPSR 0x10 #define SSPIMSC 0x14 #define SSPRIS 0x18 #define SSPMIS 0x1c #define SSPICR 0x20 #define REG(x) (((volatile unsigned char *)SSPBASE)[x]) #define WREG(x) (((volatile unsigned int *)SSPBASE)[(x)/sizeof(unsigned int)]) #define TNF (REG(SSPSR) & (1<<1)) #define RNE (REG(SSPSR) & (1<<2)) #define FP0XVAL (*((volatile unsigned int *) 0x3FFFC014)) #define FP0XSET (*((volatile unsigned int *) 0x3FFFC018)) #define FP0XCLR (*((volatile unsigned int *) 0x3FFFC01C)) void init_spi(void) { WREG(SSPCR0) = 0x1f07; /* SPI clock = PCLK/64, mode 0, 8 bits */ // WREG(SSPCR0) = 0xff07; /* Set to 0x0007 later */ REG(SSPCPSR) = 2; /* Divide PCLK by 2 */ REG(SSPCR1) = 0x0002; /* Enable SSP, Master mode */ } void spi_speedup(void) { #if 1 WREG(SSPCR0) = 0x0107; /* SPI clock = PCLK/4, mode 0, 8 bits */ #endif } void spi_write_byte(char byte) { unsigned int dummy; while (!TNF) ; WREG(SSPDR) = byte; while (!RNE) ; dummy = REG(SSPDR); #ifdef SPIDEBUG putstr(">"); puthex(byte); putstr("("); puthex(dummy); putstr(") "); #endif } char spi_read_byte(void) { char byte; while (!TNF) ; WREG(SSPDR) = 0xff; while (!RNE) ; byte = (char) REG(SSPDR); #ifdef SPIDEBUG putstr("<"); puthex(byte); putstr(" "); #endif return byte; } void spi_write_bytes(char *data, int len) { while (len--) spi_write_byte(*data++); } void spi_read_bytes(char *data, int len) { while (len--) *data++ = spi_read_byte(); } void spi_transaction_start(void) { FP0XCLR = 0x00200000; } void spi_transaction_stop(void) { FP0XSET = 0x00200000; } void spi_drain(void) { char byte; putstr("Draining:"); while (RNE) { byte = (char) REG(SSPDR); putstr(" "); puthex(byte); } putstr("\r\n"); }