/***************************************************************************** ** Function name: LoopbackTest ** ** Descriptions: Loopback test ** ** parameters: port # ** Returned value: None ** *****************************************************************************/ void SSP_LoopbackTest( uint8_t portNum ) { uint32_t i; if ( portNum == 0 ) { #if !USE_CS /* Set SSEL pin to output low. */ GPIOSetBitValue( PORT0, 2, 0 ); #endif i = 0; while ( i <= SSP_BUFSIZE ) { /* to check the RXIM and TXIM interrupt, I send a block data at one time based on the FIFOSIZE(8). */ SSP_Send( portNum, (uint8_t *)&src_addr[i], FIFOSIZE ); /* If RX interrupt is enabled, below receive routine can be also handled inside the ISR. */ SSP_Receive( portNum, (uint8_t *)&dest_addr[i], FIFOSIZE ); i += FIFOSIZE; } #if !USE_CS /* Set SSEL pin to output high. */ GPIOSetBitValue( PORT0, 2, 1 ); #endif } else { #if !USE_CS /* Set SSEL pin to output low. */ GPIOSetBitValue( PORT1, 23, 0 ); #endif i = 0; while ( i <= SSP_BUFSIZE ) { /* to check the RXIM and TXIM interrupt, I send a block data at one time based on the FIFOSIZE(8). */ SSP_Send( portNum, (uint8_t *)&src_addr[i], FIFOSIZE ); /* If RX interrupt is enabled, below receive routine can be also handled inside the ISR. */ SSP_Receive( portNum, (uint8_t *)&dest_addr[i], FIFOSIZE ); i += FIFOSIZE; } #if !USE_CS /* Set SSEL pin to output high. */ GPIOSetBitValue( PORT1, 23, 1 ); #endif } return; }
int SPI::write(int value) { int len = (_bits + 7)/8; int i; for (i = len-1; i >= 0; i--) { src_addr[i] = value & 0xFF; value = value >> 8; } return SSP_Send(SSP_NUM, src_addr, len); }
void max11040_hw_init( void ) { int i; /* *** configure SPI *** */ /* setup pins for SSP (SCK, MISO, MOSI, SSEL) */ PINSEL1 |= SSP_PINSEL1_SCK | SSP_PINSEL1_MISO | SSP_PINSEL1_MOSI | SSP_PINSEL1_SSEL; /* setup SSP */ SSPCR0 = SSPCR0_VAL;; SSPCR1 = SSPCR1_VAL; SSPCPSR = 0x02; /* initialize interrupt vector */ VICIntSelect &= ~VIC_BIT( VIC_SPI1 ); /* SPI1 selected as IRQ */ VICIntEnable = VIC_BIT( VIC_SPI1 ); /* enable it */ _VIC_CNTL(SPI1_VIC_SLOT) = VIC_ENABLE | VIC_SPI1; _VIC_ADDR(SPI1_VIC_SLOT) = (uint32_t)SSP_ISR; /* address of the ISR */ /* *** configure DRDY pin*** */ /* connected pin to EXINT */ MAXM_DRDY_PINSEL |= MAXM_DRDY_PINSEL_VAL << MAXM_DRDY_PINSEL_BIT; SetBit(EXTMODE, MAXM_DRDY_EINT); /* EINT is edge trigered */ ClearBit(EXTPOLAR, MAXM_DRDY_EINT); /* EINT is trigered on falling edge */ SetBit(EXTINT, MAXM_DRDY_EINT); /* clear pending EINT */ /* initialize interrupt vector */ VICIntSelect &= ~VIC_BIT( MAXM_DRDY_VIC_IT ); /* select EINT as IRQ source */ VICIntEnable = VIC_BIT( MAXM_DRDY_VIC_IT ); /* enable it */ _VIC_CNTL(MAX11040_DRDY_VIC_SLOT) = VIC_ENABLE | MAXM_DRDY_VIC_IT; _VIC_ADDR(MAX11040_DRDY_VIC_SLOT) = (uint32_t)EXTINT_ISR; /* address of the ISR */ /* write configuration register */ SSP_Send(0x60); /* wr conf */ for (i=0; i<MAXM_NB_ADCS; i++) { SSP_Send(0x40); /* adcx: reset */ } SSP_Enable(); SSP_ClearRti(); SSP_EnableRti(); }
/***************************************************************************** ** Function name: LoopbackTest ** ** Descriptions: Loopback test ** ** parameters: port # ** Returned value: None ** *****************************************************************************/ void SSP_LoopbackTest(SPIDef * port) { uint32_t i; /* Set SSEL pin to output low. */ digitalWrite( port->SSel, LOW ); i = 0; while ( i <= SSP_BUFSIZE ) { /* to check the RXIM and TXIM interrupt, I send a block data at one time based on the FIFOSIZE(8). */ SSP_Send( port, (uint8_t *)&src_addr[i], FIFOSIZE ); /* If RX interrupt is enabled, below receive routine can be also handled inside the ISR. */ SSP_Receive( port, (uint8_t *)&dest_addr[i], FIFOSIZE ); i += FIFOSIZE; } /* Set SSEL pin to output high. */ digitalWrite(port->SSel, HIGH ); return; }
void EXTINT_ISR(void) { ISR_ENTRY(); if (num_irqs++ == 5) { /* switch SSEL P0.20 to be used as GPIO */ PINSEL1 &= ~(3 << 8); IO0DIR |= 1 << 20; max11040_status = MAX11040_DATA2; } if (max11040_status == MAX11040_DATA2) { #ifdef LOGGER max11040_timestamp[max11040_buf_in] = getclock(); #endif MaxmSelect(); /* read data */ SSP_Send(0xF0); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); max11040_count = 0; } /* clear EINT */ SetBit(EXTINT, MAXM_DRDY_EINT); VICVectAddr = 0x00000000; /* clear this interrupt from the VIC */ ISR_EXIT(); }
/****************************************************************************** ** Main Function main() ******************************************************************************/ int main (void) { uint32_t i; #if SSP_DEBUG int8_t temp[2]; #endif SystemCoreClockUpdate(); #if SSP_DEBUG UARTInit(115200); #endif SSP_IOConfig( SSP_NUM ); SSP_Init( SSP_NUM ); for ( i = 0; i < SSP_BUFSIZE; i++ ) { src_addr[i] = (uint8_t)i; dest_addr[i] = 0; } #if TX_RX_ONLY /* For the inter-board communication, one board is set as master transmit, the other is set to slave receive. */ #if SSP_SLAVE /* Slave receive */ SSP_Receive( SSP_NUM, (uint8_t *)dest_addr, SSP_BUFSIZE ); for ( i = 0; i < SSP_BUFSIZE; i++ ) { if ( src_addr[i] != dest_addr[i] ) { while ( 1 ); /* Verification failure, fatal error */ } } #else /* Master transmit */ SSP_Send( SSP_NUM, (uint8_t *)src_addr, SSP_BUFSIZE); #endif #else /* TX_RX_ONLY=0, it's either an internal loopback test within SSP peripheral or communicate with a serial EEPROM. */ #if LOOPBACK_MODE SSP_LoopbackTest( SSP_NUM ); #else SSP_SEEPROMTest( SSP_NUM ); /* If SW CLK is used as SSP clock, change the setting before serial EEPROM test, restore after the test. */ #ifdef __SWD_DISABLED LPC_IOCON->SWCLK_PIO0_10 &= ~0x07; /* Restore SWD CLK */ #endif #endif /* endif NOT LOOPBACK_MODE */ #if LOOPBACK_MODE for ( i = 0; i < SSP_BUFSIZE; i++ ) #else /* for EEPROM test, verifying, ignore the difference in the first four bytes which are used as command and parameters. */ for ( i = SFLASH_INDEX; i < SSP_BUFSIZE; i++ ) #endif { if ( src_addr[i] != dest_addr[i] ) { #if SSP_DEBUG temp[0] = (dest_addr[i] & 0xF0) >> 4; if ( (temp[0] >= 0) && (temp[0] <= 9) ) { temp[0] += 0x30; } else { temp[0] -= 0x0A; temp[0] += 0x41; } temp[1] = dest_addr[i] & 0x0F; if ( (temp[1] >= 0) && (temp[1] <= 9) ) { temp[1] += 0x30; } else { temp[1] -= 0x0A; temp[1] += 0x41; } UARTSend((uint8_t *)&temp[0], 2); UARTSend((uint8_t *)"\r\n", 2); #endif while( 1 ); /* Verification failed */ } }
/***************************************************************************** ** Function name: SEEPROMTest ** ** Descriptions: Serial EEPROM(Atmel 25xxx) test ** ** parameters: port # ** Returned value: None ** *****************************************************************************/ void SSP_SEEPROMTest( uint8_t portNum ) { uint32_t i, timeout; if ( portNum == 0 ) { LPC_IOCON->PIO0_2 &= ~0x07; /* SSP SSEL is a GPIO pin */ GPIOSetBitValue( PORT0, 2, 1 ); /* port0, bit 2 is set to GPIO output and high */ GPIOSetDir( PORT0, 2, 1 ); GPIOSetBitValue( PORT0, 2, 0 ); /* Test Atmel AT25DF041 Serial flash. */ src_addr[0] = WREN; /* set write enable latch */ SSP_Send( portNum, (uint8_t *)src_addr, 1 ); GPIOSetBitValue( PORT0, 2, 1 ); for ( i = 0; i < 0x80; i++ ); /* delay minimum 250ns */ GPIOSetBitValue( PORT0, 2, 0 ); src_addr[0] = RDSR; /* check status to see if write enabled is latched */ SSP_Send( portNum, (uint8_t *)src_addr, 1 ); SSP_Receive( portNum, (uint8_t *)dest_addr, 1 ); GPIOSetBitValue( PORT0, 2, 1 ); if ( (dest_addr[0] & (RDSR_WEN|RDSR_RDY)) != RDSR_WEN ) /* bit 0 to 0 is ready, bit 1 to 1 is write enable */ { while ( 1 ); } for ( i = 0; i < 0x80; i++ ); /* delay minimum 250ns */ GPIOSetBitValue( PORT0, 2, 0 ); src_addr[0] = WRSR; src_addr[1] = 0x00; /* Make the whole device unprotected. */ SSP_Send( portNum, (uint8_t *)src_addr, 2 ); GPIOSetBitValue( PORT0, 2, 1 ); for ( i = 0; i < 0x80; i++ ); /* delay minimum 250ns */ GPIOSetBitValue( PORT0, 2, 0 ); src_addr[0] = RDSR; /* check status to see if write enabled is latched */ SSP_Send( portNum, (uint8_t *)src_addr, 1 ); SSP_Receive( portNum, (uint8_t *)dest_addr, 1 ); GPIOSetBitValue( PORT0, 2, 1 ); if ( (dest_addr[0] & (RDSR_WEN|RDSR_RDY)) != RDSR_WEN ) /* bit 0 to 0 is ready, bit 1 to 1 is write enable */ { while ( 1 ); } for ( i = 0; i < 0x80; i++ ); /* delay minimum 250ns */ GPIOSetBitValue( PORT0, 2, 0 ); src_addr[0] = CHIP_ERASE; /* Write command is 0x02, low 256 bytes only */ SSP_Send( portNum, (uint8_t *)src_addr, 1 ); GPIOSetBitValue( PORT0, 2, 1 ); for ( i = 0; i < 0x1400000; i++ ); /* Be careful with the dumb delay, it may vary depending on the system clock. */ GPIOSetBitValue( PORT0, 2, 0 ); src_addr[0] = RDSR; /* check status to see if write enabled is latched */ SSP_Send( portNum, (uint8_t *)src_addr, 1 ); SSP_Receive( portNum, (uint8_t *)dest_addr, 1 ); GPIOSetBitValue( PORT0, 2, 1 ); if ( (dest_addr[0] & (RDSR_EPE|RDSR_RDY)) != 0x0 ) /* bit 0 to 0 is ready, bit 1 to 1 is write enable */ { while ( 1 ); } GPIOSetBitValue( PORT0, 2, 0 ); /* Test Atmel AT25DF041 Serial flash. */ src_addr[0] = WREN; /* set write enable latch */ SSP_Send( portNum, (uint8_t *)src_addr, 1 ); GPIOSetBitValue( PORT0, 2, 1 ); for ( i = 0; i < 0x80; i++ ); /* delay minimum 250ns */ GPIOSetBitValue( PORT0, 2, 0 ); src_addr[0] = RDSR; /* check status to see if write enabled is latched */ SSP_Send( portNum, (uint8_t *)src_addr, 1 ); SSP_Receive( portNum, (uint8_t *)dest_addr, 1 ); GPIOSetBitValue( PORT0, 2, 1 ); if ( (dest_addr[0] & (RDSR_WEN|RDSR_RDY)) != RDSR_WEN ) /* bit 0 to 0 is ready, bit 1 to 1 is write enable */ { while ( 1 ); } for ( i = 0; i < SSP_BUFSIZE; i++ ) /* Init RD and WR buffer */ { src_addr[i+SFLASH_INDEX] = i; /* leave four bytes for cmd and offset(16 bits) */ dest_addr[i] = 0; } /* please note the first four bytes of WR and RD buffer is used for commands and offset, so only 4 through SSP_BUFSIZE is used for data read, write, and comparison. */ GPIOSetBitValue( PORT0, 2, 0 ); src_addr[0] = WRITE; /* Write command is 0x02, low 256 bytes only */ src_addr[1] = 0x00; /* write address offset MSB is 0x00 */ src_addr[2] = 0x00; /* write address offset LSB is 0x00 */ src_addr[3] = 0x00; /* write address offset LSB is 0x00 */ SSP_Send( portNum, (uint8_t *)src_addr, SSP_BUFSIZE ); GPIOSetBitValue( PORT0, 2, 1 ); for ( i = 0; i < 0x400000; i++ ); /* Be careful with the dumb delay, it may vary depending on the system clock. */ timeout = 0; while ( timeout < MAX_TIMEOUT ) { GPIOSetBitValue( PORT0, 2, 0 ); src_addr[0] = RDSR; /* check status to see if write cycle is done or not */ SSP_Send( portNum, (uint8_t *)src_addr, 1); SSP_Receive( portNum, (uint8_t *)dest_addr, 1 ); GPIOSetBitValue( PORT0, 2, 1 ); if ( (dest_addr[0] & RDSR_RDY) == 0x00 ) /* bit 0 to 0 is ready */ { break; } timeout++; } if ( timeout == MAX_TIMEOUT ) { while ( 1 ); } for ( i = 0; i < 0x80; i++ ); /* delay, minimum 250ns */ GPIOSetBitValue( PORT0, 2, 0 ); src_addr[0] = READ; /* Read command is 0x03, low 256 bytes only */ src_addr[1] = 0x00; /* Read address offset MSB is 0x00 */ src_addr[2] = 0x00; /* Read address offset LSB is 0x00 */ src_addr[3] = 0x00; /* Read address offset LSB is 0x00 */ SSP_Send( portNum, (uint8_t *)src_addr, SFLASH_INDEX ); SSP_Receive( portNum, (uint8_t *)&dest_addr[SFLASH_INDEX], SSP_BUFSIZE-SFLASH_INDEX ); GPIOSetBitValue( PORT0, 2, 1 ); } else /* Port 1 */ { /* Test on Port 0 only. */ while ( 1 ); } return; }
void glcd_spi_write(uint8_t c) { GLCD_SELECT(); SSP_Send(PCD8544_SPI_PORT_NUMBER,&c,1); GLCD_DESELECT(); }
void glcd_spi_write(uint8_t c) { GLCD_SELECT(); SSP_Send(CONTROLLER_SPI_PORT_NUMBER,&c,1); GLCD_DESELECT(); }
static void SSP_ISR(void) { int i; ISR_ENTRY(); switch (max11040_status) { case MAX11040_RESET: { /* read dummy control byte reply */ uint8_t foo __attribute__ ((unused)); foo = SSPDR; foo = SSPDR; /* write configuration register */ SSP_Send(0x60); /* wr conf */ SSP_Send(0x30); /* adc0: en24bit, xtalen, no faultdis */ for (i=1; i<MAXM_NB_ADCS; i++) { SSP_Send(0x20); /* adcx: en24bit, no xtalen, no faultdis */ } max11040_status = MAX11040_CONF; SSP_ClearRti(); } break; case MAX11040_CONF: { /* read dummy control byte reply */ uint8_t foo __attribute__ ((unused)); foo = SSPDR; for (i=0; i<MAXM_NB_ADCS; i++) { foo = SSPDR; } /* write sampling instant register */ SSP_Send(0x40); /* wr instant */ for (i=0; i<MAXM_NB_ADCS; i++) { SSP_Send(0); /* adcx: no delay */ SSP_Send(0); SSP_Send(0); SSP_Send(0); } max11040_status = MAX11040_INSTANT; SSP_ClearRti(); } break; case MAX11040_INSTANT: { /* read dummy control byte reply */ uint8_t foo __attribute__ ((unused)); foo = SSPDR; for (i=0; i<MAXM_NB_ADCS; i++) { foo = SSPDR; foo = SSPDR; foo = SSPDR; foo = SSPDR; } /* write data rate control register */ SSP_Send(0x50); /* wr rate */ SSP_Send(0x26); /* adc: 250.1 sps */ SSP_Send(0x00); max11040_status = MAX11040_RATE; SSP_ClearRti(); } break; case MAX11040_RATE: { uint8_t foo __attribute__ ((unused)); foo = SSPDR; foo = SSPDR; foo = SSPDR; /* read data register */ SSP_Send(0xF0); /* rd data */ for (i=0; i<MAXM_NB_ADCS; i++) { SSP_Send(0x00); /* adcx: data */ SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); } max11040_status = MAX11040_DATA; SSP_ClearRti(); } break; case MAX11040_DATA: { uint8_t foo __attribute__ ((unused)); foo = SSPDR; for (i=0; i<MAXM_NB_ADCS; i++) { foo = SSPDR; foo = SSPDR; foo = SSPDR; foo = SSPDR; foo = SSPDR; foo = SSPDR; foo = SSPDR; foo = SSPDR; foo = SSPDR; foo = SSPDR; foo = SSPDR; foo = SSPDR; } /* read data */ /* read data register */ SSP_Send(0xF0); /* rd data */ for (i=0; i<MAXM_NB_ADCS; i++) { SSP_Send(0x00); /* adc0: data */ SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); } SSP_ClearRti(); } break; case MAX11040_DATA2: { uint8_t foo __attribute__ ((unused)); SSP_ClearRti(); SSP_ClearRxi(); if (max11040_count <= MAXM_NB_CHAN+2) { SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); SSP_Send(0x00); } if (max11040_count == 0) foo = SSPDR; max11040_values[max11040_buf_in][max11040_count] = SSPDR << 16; max11040_values[max11040_buf_in][max11040_count] |= SSPDR << 8; max11040_values[max11040_buf_in][max11040_count] |= SSPDR; if (max11040_values[max11040_buf_in][max11040_count] & 0x800000) max11040_values[max11040_buf_in][max11040_count] |= 0xFF000000; max11040_count++; max11040_values[max11040_buf_in][max11040_count] = SSPDR << 16; max11040_values[max11040_buf_in][max11040_count] |= SSPDR << 8; max11040_values[max11040_buf_in][max11040_count] |= SSPDR; if (max11040_values[max11040_buf_in][max11040_count] & 0x800000) max11040_values[max11040_buf_in][max11040_count] |= 0xFF000000; max11040_count++; if (max11040_count == MAXM_NB_CHAN) { MaxmUnselect(); max11040_data = MAX11040_DATA_AVAILABLE; i = max11040_buf_in+1; if (i >= MAX11040_BUF_SIZE) i=0; if (i != max11040_buf_out) { max11040_buf_in = i; } else { //throw error; } } } break; } VICVectAddr = 0x00000000; /* clear this interrupt from the VIC */ ISR_EXIT(); }