diff options
Diffstat (limited to 'bsp/lpc176x/drivers/spi.c')
| -rw-r--r-- | bsp/lpc176x/drivers/spi.c | 229 |
1 files changed, 119 insertions, 110 deletions
diff --git a/bsp/lpc176x/drivers/spi.c b/bsp/lpc176x/drivers/spi.c index a6561195c5..ef328bc793 100644 --- a/bsp/lpc176x/drivers/spi.c +++ b/bsp/lpc176x/drivers/spi.c @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + #include "LPC17xx.h" /* LPC17xx definitions */ #include "spi.h" @@ -21,98 +30,98 @@ static uint8_t LPC17xx_SPI_SendRecvByte (uint8_t byte_s); /* Initialize the SSP0, SSP0_PCLK=CCLK=72MHz */ void LPC17xx_SPI_Init (void) { - uint32_t dummy; + uint32_t dummy; - dummy = dummy; // avoid warning + dummy = dummy; // avoid warning #if 0 - /* Initialize and enable the SSP0 Interface module. */ - LPC_SC->PCONP |= (1 << 21); /* Enable power to SSPI0 block */ + /* Initialize and enable the SSP0 Interface module. */ + LPC_SC->PCONP |= (1 << 21); /* Enable power to SSPI0 block */ - /* SSEL is GPIO, output set to high. */ - LPC_GPIO0->FIODIR |= (1<<16); /* P0.16 is output */ - LPC_PINCON->PINSEL1 &= ~(3<<0); /* P0.16 SSEL (used as GPIO) */ - LPC17xx_SPI_DeSelect (); /* set P0.16 high (SSEL inactiv) */ + /* SSEL is GPIO, output set to high. */ + LPC_GPIO0->FIODIR |= (1<<16); /* P0.16 is output */ + LPC_PINCON->PINSEL1 &= ~(3<<0); /* P0.16 SSEL (used as GPIO) */ + LPC17xx_SPI_DeSelect (); /* set P0.16 high (SSEL inactiv) */ - /* SCK, MISO, MOSI are SSP pins. */ - LPC_PINCON->PINSEL0 &= ~(3UL<<30); /* P0.15 cleared */ - LPC_PINCON->PINSEL0 |= (2UL<<30); /* P0.15 SCK0 */ - LPC_PINCON->PINSEL1 &= ~((3<<2) | (3<<4)); /* P0.17, P0.18 cleared */ - LPC_PINCON->PINSEL1 |= ((2<<2) | (2<<4)); /* P0.17 MISO0, P0.18 MOSI0 */ + /* SCK, MISO, MOSI are SSP pins. */ + LPC_PINCON->PINSEL0 &= ~(3UL<<30); /* P0.15 cleared */ + LPC_PINCON->PINSEL0 |= (2UL<<30); /* P0.15 SCK0 */ + LPC_PINCON->PINSEL1 &= ~((3<<2) | (3<<4)); /* P0.17, P0.18 cleared */ + LPC_PINCON->PINSEL1 |= ((2<<2) | (2<<4)); /* P0.17 MISO0, P0.18 MOSI0 */ #else - LPC_SC->PCONP |= (1 << 21); /* Enable power to SSPI0 block */ + LPC_SC->PCONP |= (1 << 21); /* Enable power to SSPI0 block */ - /* SSEL is GPIO, output set to high. */ - LPC_GPIO1->FIODIR |= (1<<21); /* P1.21 is output */ - LPC_GPIO1->FIOPIN |= (1<<21); /* set P1.21 high (SSEL inact.)*/ - LPC_PINCON->PINSEL3 &= ~(0<<10); /* P1.21 SSEL (used as GPIO) */ + /* SSEL is GPIO, output set to high. */ + LPC_GPIO1->FIODIR |= (1<<21); /* P1.21 is output */ + LPC_GPIO1->FIOPIN |= (1<<21); /* set P1.21 high (SSEL inact.)*/ + LPC_PINCON->PINSEL3 &= ~(0<<10); /* P1.21 SSEL (used as GPIO) */ - /* P3.26 is SD Card Power Supply Enable Pin */ - LPC_GPIO3->FIODIR |= (1<<26); /* P3.26 is output */ - LPC_GPIO3->FIOPIN &= ~(1<<26); /* set P3.26 low(enable power) */ + /* P3.26 is SD Card Power Supply Enable Pin */ + LPC_GPIO3->FIODIR |= (1<<26); /* P3.26 is output */ + LPC_GPIO3->FIOPIN &= ~(1<<26); /* set P3.26 low(enable power) */ - /* SCK, MISO, MOSI are SSP pins. */ - LPC_PINCON->PINSEL3 &= ~(3UL<<8); /* P1.20 cleared */ - LPC_PINCON->PINSEL3 |= (3UL<<8); /* P1.20 SCK0 */ - LPC_PINCON->PINSEL3 &= ~((3<<14) | (3<<16)); /* P1.23, P1.24 cleared */ - LPC_PINCON->PINSEL3 |= ((3<<14) | (3<<16)); /* P1.23 MISO0, P1.24 MOSI0 */ + /* SCK, MISO, MOSI are SSP pins. */ + LPC_PINCON->PINSEL3 &= ~(3UL<<8); /* P1.20 cleared */ + LPC_PINCON->PINSEL3 |= (3UL<<8); /* P1.20 SCK0 */ + LPC_PINCON->PINSEL3 &= ~((3<<14) | (3<<16)); /* P1.23, P1.24 cleared */ + LPC_PINCON->PINSEL3 |= ((3<<14) | (3<<16)); /* P1.23 MISO0, P1.24 MOSI0 */ #endif - /* PCLK_SSP0=CCLK */ - LPC_SC->PCLKSEL1 &= ~(3<<10); /* PCLKSP0 = CCLK/4 (18MHz) */ - LPC_SC->PCLKSEL1 |= (1<<10); /* PCLKSP0 = CCLK (72MHz) */ + /* PCLK_SSP0=CCLK */ + LPC_SC->PCLKSEL1 &= ~(3<<10); /* PCLKSP0 = CCLK/4 (18MHz) */ + LPC_SC->PCLKSEL1 |= (1<<10); /* PCLKSP0 = CCLK (72MHz) */ - LPC_SSP0->CR0 = 0x0007; /* 8Bit, CPOL=0, CPHA=0 */ - LPC_SSP0->CR1 = 0x0002; /* SSP0 enable, master */ + LPC_SSP0->CR0 = 0x0007; /* 8Bit, CPOL=0, CPHA=0 */ + LPC_SSP0->CR1 = 0x0002; /* SSP0 enable, master */ - LPC17xx_SPI_SetSpeed (SPI_SPEED_400kHz); + LPC17xx_SPI_SetSpeed (SPI_SPEED_400kHz); - /* wait for busy gone */ - while( LPC_SSP0->SR & ( 1 << SSPSR_BSY ) ); + /* wait for busy gone */ + while( LPC_SSP0->SR & ( 1 << SSPSR_BSY ) ); - /* drain SPI RX FIFO */ - while( LPC_SSP0->SR & ( 1 << SSPSR_RNE ) ) - { - dummy = LPC_SSP0->DR; - } + /* drain SPI RX FIFO */ + while( LPC_SSP0->SR & ( 1 << SSPSR_RNE ) ) + { + dummy = LPC_SSP0->DR; + } } /* Close SSP0 */ void LPC17xx_SPI_DeInit( void ) { - // disable SPI - LPC_SSP0->CR1 = 0; + // disable SPI + LPC_SSP0->CR1 = 0; #if 0 - // Pins to GPIO - LPC_PINCON->PINSEL0 &= ~(3UL<<30); - LPC_PINCON->PINSEL1 &= ~((3<<2) | (3<<4)); + // Pins to GPIO + LPC_PINCON->PINSEL0 &= ~(3UL<<30); + LPC_PINCON->PINSEL1 &= ~((3<<2) | (3<<4)); #else - LPC_PINCON->PINSEL3 &= ~(3UL<<8); /* P1.20 cleared */ - LPC_PINCON->PINSEL3 &= ~((3<<14) | (3<<16)); /* P1.23, P1.24 cleared */ + LPC_PINCON->PINSEL3 &= ~(3UL<<8); /* P1.20 cleared */ + LPC_PINCON->PINSEL3 &= ~((3<<14) | (3<<16)); /* P1.23, P1.24 cleared */ #endif - // disable SSP power - LPC_SC->PCONP &= ~(1 << 21); + // disable SSP power + LPC_SC->PCONP &= ~(1 << 21); } /* Set a SSP0 clock speed to desired value. */ void LPC17xx_SPI_SetSpeed (uint8_t speed) { - speed &= 0xFE; - if ( speed < 2 ) { - speed = 2 ; - } - LPC_SSP0->CPSR = speed; + speed &= 0xFE; + if ( speed < 2 ) { + speed = 2 ; + } + LPC_SSP0->CPSR = speed; } /* SSEL: low */ void LPC17xx_SPI_Select () { #if 0 - LPC_GPIO0->FIOPIN &= ~(1<<16); + LPC_GPIO0->FIOPIN &= ~(1<<16); #else - LPC_GPIO1->FIOPIN &= ~(1<<21); /* SSEL is GPIO, set to high. */ + LPC_GPIO1->FIOPIN &= ~(1<<21); /* SSEL is GPIO, set to high. */ #endif } @@ -120,41 +129,41 @@ void LPC17xx_SPI_Select () void LPC17xx_SPI_DeSelect () { #if 0 - LPC_GPIO0->FIOPIN |= (1<<16); + LPC_GPIO0->FIOPIN |= (1<<16); #else - LPC_GPIO1->FIOPIN |= (1<<21); /* SSEL is GPIO, set to high. */ + LPC_GPIO1->FIOPIN |= (1<<21); /* SSEL is GPIO, set to high. */ #endif } /* Send one byte then recv one byte of response. */ static uint8_t LPC17xx_SPI_SendRecvByte (uint8_t byte_s) { - uint8_t byte_r; + uint8_t byte_r; - LPC_SSP0->DR = byte_s; - while (LPC_SSP0->SR & (1 << SSPSR_BSY) /*BSY*/); /* Wait for transfer to finish */ - byte_r = LPC_SSP0->DR; + LPC_SSP0->DR = byte_s; + while (LPC_SSP0->SR & (1 << SSPSR_BSY) /*BSY*/); /* Wait for transfer to finish */ + byte_r = LPC_SSP0->DR; - return byte_r; /* Return received value */ + return byte_r; /* Return received value */ } /* Send one byte */ void LPC17xx_SPI_SendByte (uint8_t data) { - LPC17xx_SPI_SendRecvByte (data); + LPC17xx_SPI_SendRecvByte (data); } /* Recv one byte */ uint8_t LPC17xx_SPI_RecvByte () { - return LPC17xx_SPI_SendRecvByte (0xFF); + return LPC17xx_SPI_SendRecvByte (0xFF); } /* Release SSP0 */ void LPC17xx_SPI_Release (void) { - LPC17xx_SPI_DeSelect (); - LPC17xx_SPI_RecvByte (); + LPC17xx_SPI_DeSelect (); + LPC17xx_SPI_RecvByte (); } @@ -163,66 +172,66 @@ void LPC17xx_SPI_Release (void) #define FIFO_ELEM 8 /* Receive btr (must be multiple of 4) bytes of data and store in buff. */ -void LPC17xx_SPI_RecvBlock_FIFO (uint8_t *buff, uint32_t btr) +void LPC17xx_SPI_RecvBlock_FIFO (uint8_t *buff, uint32_t btr) { - uint32_t hwtr, startcnt, i, rec; + uint32_t hwtr, startcnt, i, rec; - hwtr = btr/2; /* byte number in unit of short */ - if ( btr < FIFO_ELEM ) { - startcnt = hwtr; - } else { - startcnt = FIFO_ELEM; - } + hwtr = btr/2; /* byte number in unit of short */ + if ( btr < FIFO_ELEM ) { + startcnt = hwtr; + } else { + startcnt = FIFO_ELEM; + } - LPC_SSP0 -> CR0 |= 0x0f; /* DSS to 16 bit */ + LPC_SSP0 -> CR0 |= 0x0f; /* DSS to 16 bit */ - for ( i = startcnt; i; i-- ) { - LPC_SSP0 -> DR = 0xffff; /* fill TX FIFO, prepare clk for receive */ - } + for ( i = startcnt; i; i-- ) { + LPC_SSP0 -> DR = 0xffff; /* fill TX FIFO, prepare clk for receive */ + } - do { - while ( !(LPC_SSP0->SR & ( 1 << SSPSR_RNE ) ) ) { - // wait for data in RX FIFO (RNE set) - } - rec = LPC_SSP0->DR; - if ( i < ( hwtr - startcnt ) ) { - LPC_SSP0->DR = 0xffff; /* fill TX FIFO, prepare clk for receive */ - } - *buff++ = (uint8_t)(rec>>8); - *buff++ = (uint8_t)(rec); - i++; - } while ( i < hwtr ); + do { + while ( !(LPC_SSP0->SR & ( 1 << SSPSR_RNE ) ) ) { + // wait for data in RX FIFO (RNE set) + } + rec = LPC_SSP0->DR; + if ( i < ( hwtr - startcnt ) ) { + LPC_SSP0->DR = 0xffff; /* fill TX FIFO, prepare clk for receive */ + } + *buff++ = (uint8_t)(rec>>8); + *buff++ = (uint8_t)(rec); + i++; + } while ( i < hwtr ); - LPC_SSP0->CR0 &= ~0x08; /* DSS to 8 bit */ + LPC_SSP0->CR0 &= ~0x08; /* DSS to 8 bit */ } /* Send 512 bytes of data block (stored in buff). */ void LPC17xx_SPI_SendBlock_FIFO (const uint8_t *buff) { - uint32_t cnt; - uint16_t data; + uint32_t cnt; + uint16_t data; - LPC_SSP0->CR0 |= 0x0f; /* DSS to 16 bit */ + LPC_SSP0->CR0 |= 0x0f; /* DSS to 16 bit */ - /* fill the FIFO unless it is full */ - for ( cnt = 0; cnt < ( 512 / 2 ); cnt++ ) - { - /* wait for TX FIFO not full (TNF) */ - while ( !( LPC_SSP0->SR & ( 1 << SSPSR_TNF ) ) ); + /* fill the FIFO unless it is full */ + for ( cnt = 0; cnt < ( 512 / 2 ); cnt++ ) + { + /* wait for TX FIFO not full (TNF) */ + while ( !( LPC_SSP0->SR & ( 1 << SSPSR_TNF ) ) ); - data = (*buff++) << 8; - data |= *buff++; - LPC_SSP0->DR = data; - } + data = (*buff++) << 8; + data |= *buff++; + LPC_SSP0->DR = data; + } - /* wait for BSY gone */ - while ( LPC_SSP0->SR & ( 1 << SSPSR_BSY ) ); + /* wait for BSY gone */ + while ( LPC_SSP0->SR & ( 1 << SSPSR_BSY ) ); - /* drain receive FIFO */ - while ( LPC_SSP0->SR & ( 1 << SSPSR_RNE ) ) { - data = LPC_SSP0->DR; - } + /* drain receive FIFO */ + while ( LPC_SSP0->SR & ( 1 << SSPSR_RNE ) ) { + data = LPC_SSP0->DR; + } - LPC_SSP0->CR0 &= ~0x08; /* DSS to 8 bit */ + LPC_SSP0->CR0 &= ~0x08; /* DSS to 8 bit */ } #endif /* USE_FIFO */ |
