--- /dev/null
+/* Based on MMCv3/SDv1/SDv2 (in SPI mode) control module (C)ChaN, 2009 \r
+Modifications (C) 2010 Real Time Engineers ltd. */\r
+\r
+#include "FreeRTOS.h"\r
+#include "diskio.h"\r
+\r
+void disk_init_spi( void );\r
+\r
+/* Definitions for MMC/SDC command */\r
+#define CMD0 ( 0x40 + 0 ) /* GO_IDLE_STATE */\r
+#define CMD1 ( 0x40 + 1 ) /* SEND_OP_COND (MMC) */\r
+#define ACMD41 ( 0xC0 + 41 ) /* SEND_OP_COND (SDC) */\r
+#define CMD8 ( 0x40 + 8 ) /* SEND_IF_COND */\r
+#define CMD9 ( 0x40 + 9 ) /* SEND_CSD */\r
+#define CMD10 ( 0x40 + 10 ) /* SEND_CID */\r
+#define CMD12 ( 0x40 + 12 ) /* STOP_TRANSMISSION */\r
+#define ACMD13 ( 0xC0 + 13 ) /* SD_STATUS (SDC) */\r
+#define CMD16 ( 0x40 + 16 ) /* SET_BLOCKLEN */\r
+#define CMD17 ( 0x40 + 17 ) /* READ_SINGLE_BLOCK */\r
+#define CMD18 ( 0x40 + 18 ) /* READ_MULTIPLE_BLOCK */\r
+#define CMD23 ( 0x40 + 23 ) /* SET_BLOCK_COUNT (MMC) */\r
+#define ACMD23 ( 0xC0 + 23 ) /* SET_WR_BLK_ERASE_COUNT (SDC) */\r
+#define CMD24 ( 0x40 + 24 ) /* WRITE_BLOCK */\r
+#define CMD25 ( 0x40 + 25 ) /* WRITE_MULTIPLE_BLOCK */\r
+#define CMD55 ( 0x40 + 55 ) /* APP_CMD */\r
+#define CMD58 ( 0x40 + 58 ) /* READ_OCR */\r
+\r
+/* Port Controls (Platform dependent) */\r
+#define CS_LOW() GPIO0->FIOCLR = ( 1 << 16 ) /* MMC CS = L */\r
+#define CS_HIGH() GPIO0->FIOSET = ( 1 << 16 ) /* MMC CS = H */\r
+\r
+#define SOCKWP ( 0 ) /* Write protect switch. */\r
+#define SOCKINS ( 1 << 29 ) /* Card detect switch. */\r
+#define SOCKPORT ( GPIO4->FIOPIN )\r
+#define FCLK_SLOW() /* Set slow clock (100k-400k) */\r
+#define FCLK_FAST() /* Set fast clock (depends on the CSD) */\r
+\r
+#define xmit_spi( dat ) xchg_spi( dat )\r
+#define rcvr_spi() xchg_spi( 0xFF )\r
+#define rcvr_spi_m( p ) \\r
+ SPI->SPDR = 0xFF; \\r
+ while( !( SPI->SPSR & ( 1 << 7 ) ) ); /* Check SPIF bit. */ \\r
+ *( p ) = ( BYTE ) SPI->SPDR;\r
+\r
+/*-------------------------------------------------------------------------- */\r
+\r
+static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */\r
+static volatile UINT Timer1, Timer2; /* 1000Hz decrement timer */\r
+static UINT CardType;\r
+\r
+static BYTE xchg_spi( BYTE dat )\r
+{\r
+ SPI->SPDR = dat;\r
+ while( !( SPI->SPSR & ( 1 << 7 ) ) ); /* Check SPIF bit. */\r
+ return( BYTE ) SPI->SPDR;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Wait for card ready */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+static BYTE wait_ready( void )\r
+{\r
+ BYTE res;\r
+\r
+ Timer2 = 500; /* Wait for ready in timeout of 500ms */\r
+ rcvr_spi();\r
+ do\r
+ {\r
+ res = rcvr_spi();\r
+ } while( (res != 0xFF) && Timer2 );\r
+\r
+ return res;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Deselect the card and release SPI bus */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+static void deselect( void )\r
+{\r
+ CS_HIGH();\r
+ rcvr_spi();\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Select the card and wait ready */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+static BOOL select( void ) /* TRUE:Successful, FALSE:Timeout */\r
+{\r
+ CS_LOW();\r
+ if( wait_ready() != 0xFF )\r
+ {\r
+ deselect();\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Power Control (Platform dependent) */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* When the target system does not support socket power control, there */\r
+\r
+/* is nothing to do in these functions and chk_power always returns 1. */\r
+static void power_on( void )\r
+{\r
+#if 0\r
+ /* Enable SPI1 */\r
+ SPI1CON1 = 0x013B;\r
+ SPI1CON2 = 0x0000;\r
+ _SPIEN = 1;\r
+#endif\r
+}\r
+\r
+static void power_off( void )\r
+{\r
+#if 0\r
+ select(); /* Wait for card ready */\r
+ deselect();\r
+\r
+ _SPIEN = 0; /* Disable SPI1 */\r
+\r
+ Stat |= STA_NOINIT; /* Set STA_NOINIT */\r
+#endif\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Receive a data packet from MMC */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+static BOOL rcvr_datablock( BYTE *buff, /* Data buffer to store received data */ UINT btr /* Byte count (must be multiple of 4) */ )\r
+{\r
+ BYTE token;\r
+\r
+ Timer1 = 100;\r
+ do\r
+ { /* Wait for data packet in timeout of 100ms */\r
+ token = rcvr_spi();\r
+ } while( (token == 0xFF) && Timer1 );\r
+\r
+ if( token != 0xFE )\r
+ {\r
+ return FALSE; /* If not valid data token, retutn with error */\r
+ }\r
+\r
+ do\r
+ { /* Receive the data block into buffer */\r
+ rcvr_spi_m( buff++ );\r
+ rcvr_spi_m( buff++ );\r
+ rcvr_spi_m( buff++ );\r
+ rcvr_spi_m( buff++ );\r
+ } while( btr -= 4 );\r
+ rcvr_spi(); /* Discard CRC */\r
+ rcvr_spi();\r
+\r
+ return TRUE; /* Return with success */\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Send a data packet to MMC */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+#if _READONLY == 0\r
+static BOOL xmit_datablock( const BYTE *buff, /* 512 byte data block to be transmitted */ BYTE token /* Data/Stop token */ )\r
+{\r
+ BYTE resp;\r
+ UINT bc = 512;\r
+\r
+ if( wait_ready() != 0xFF )\r
+ {\r
+ return FALSE;\r
+ }\r
+\r
+ xmit_spi( token ); /* Xmit data token */\r
+ if( token != 0xFD )\r
+ { /* Is data token */\r
+ do\r
+ { /* Xmit the 512 byte data block to MMC */\r
+ xmit_spi( *buff++ );\r
+ xmit_spi( *buff++ );\r
+ } while( bc -= 2 );\r
+ xmit_spi( 0xFF ); /* CRC (Dummy) */\r
+ xmit_spi( 0xFF );\r
+ resp = rcvr_spi(); /* Receive data response */\r
+ if( (resp & 0x1F) != 0x05 )\r
+ { /* If not accepted, return with error */\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+#endif /* _READONLY */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Send a command packet to MMC */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+static BYTE send_cmd( BYTE cmd, /* Command byte */ DWORD arg /* Argument */ )\r
+{\r
+ BYTE n, res;\r
+\r
+ if( cmd & 0x80 )\r
+ { /* ACMD<n> is the command sequense of CMD55-CMD<n> */\r
+ cmd &= 0x7F;\r
+ res = send_cmd( CMD55, 0 );\r
+ if( res > 1 )\r
+ {\r
+ return res;\r
+ }\r
+ }\r
+\r
+ /* Select the card and wait for ready */\r
+ deselect();\r
+ if( !select() )\r
+ {\r
+ return 0xFF;\r
+ }\r
+\r
+ /* Send command packet */\r
+ xmit_spi( cmd ); /* Start + Command index */\r
+ xmit_spi( (BYTE) (arg >> 24) ); /* Argument[31..24] */\r
+ xmit_spi( (BYTE) (arg >> 16) ); /* Argument[23..16] */\r
+ xmit_spi( (BYTE) (arg >> 8) ); /* Argument[15..8] */\r
+ xmit_spi( (BYTE) arg ); /* Argument[7..0] */\r
+ n = 0x01; /* Dummy CRC + Stop */\r
+ if( cmd == CMD0 )\r
+ {\r
+ n = 0x95; /* Valid CRC for CMD0(0) */\r
+ }\r
+\r
+ if( cmd == CMD8 )\r
+ {\r
+ n = 0x87; /* Valid CRC for CMD8(0x1AA) */\r
+ }\r
+\r
+ xmit_spi( n );\r
+\r
+ /* Receive command response */\r
+ if( cmd == CMD12 )\r
+ {\r
+ rcvr_spi(); /* Skip a stuff byte when stop reading */\r
+ }\r
+\r
+ n = 10; /* Wait for a valid response in timeout of 10 attempts */\r
+ do\r
+ {\r
+ res = rcvr_spi();\r
+ } while( (res & 0x80) && --n );\r
+\r
+ return res; /* Return with the response value */\r
+}\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Public Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Initialize Disk Drive */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+DSTATUS disk_initialize( BYTE drv /* Physical drive nmuber (0) */ )\r
+{\r
+ BYTE n, cmd, ty, ocr[4];\r
+\r
+ if( drv )\r
+ {\r
+ return STA_NOINIT; /* Supports only single drive */\r
+ }\r
+\r
+ if( Stat & STA_NODISK )\r
+ {\r
+ return Stat; /* No card in the socket */\r
+ }\r
+\r
+ power_on(); /* Force socket power on */\r
+ FCLK_SLOW();\r
+ for( n = 10; n; n-- )\r
+ {\r
+ rcvr_spi(); /* 80 dummy clocks */\r
+ }\r
+\r
+ ty = 0;\r
+ if( send_cmd(CMD0, 0) == 1 )\r
+ { /* Enter Idle state */\r
+ Timer1 = 1000; /* Initialization timeout of 1000 msec */\r
+ if( send_cmd(CMD8, 0x1AA) == 1 )\r
+ { /* SDv2? */\r
+ for( n = 0; n < 4; n++ )\r
+ {\r
+ ocr[n] = rcvr_spi(); /* Get trailing return value of R7 resp */\r
+ }\r
+\r
+ if( ocr[2] == 0x01 && ocr[3] == 0xAA )\r
+ { /* The card can work at vdd range of 2.7-3.6V */\r
+ while( Timer1 && send_cmd(ACMD41, 1UL << 30) );\r
+\r
+ /* Wait for leaving idle state (ACMD41 with HCS bit) */\r
+ if( Timer1 && send_cmd(CMD58, 0) == 0 )\r
+ { /* Check CCS bit in the OCR */\r
+ for( n = 0; n < 4; n++ )\r
+ {\r
+ ocr[n] = rcvr_spi();\r
+ }\r
+\r
+ ty = ( ocr[0] & 0x40 ) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC/SC) */\r
+ }\r
+ }\r
+ }\r
+ else\r
+ { /* SDv1 or MMCv3 */\r
+ if( send_cmd(ACMD41, 0) <= 1 )\r
+ {\r
+ ty = CT_SD1;\r
+ cmd = ACMD41; /* SDv1 */\r
+ }\r
+ else\r
+ {\r
+ ty = CT_MMC;\r
+ cmd = CMD1; /* MMCv3 */\r
+ }\r
+\r
+ while( Timer1 && send_cmd(cmd, 0) );\r
+\r
+ /* Wait for leaving idle state */\r
+ if( !Timer1 || send_cmd(CMD16, 512) != 0 )\r
+ { /* Set R/W block length to 512 */\r
+ ty = 0;\r
+ }\r
+ }\r
+ }\r
+\r
+ CardType = ty;\r
+ deselect();\r
+\r
+ if( ty )\r
+ { /* Initialization succeded */\r
+ Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */\r
+ FCLK_FAST();\r
+ }\r
+ else\r
+ { /* Initialization failed */\r
+ power_off();\r
+ }\r
+\r
+ return Stat;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Get Disk Status */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+DSTATUS disk_status( BYTE drv /* Physical drive nmuber (0) */ )\r
+{\r
+ if( drv )\r
+ {\r
+ return STA_NOINIT; /* Supports only single drive */\r
+ }\r
+\r
+ return Stat;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Read Sector(s) */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+DRESULT disk_read\r
+ (\r
+ BYTE drv, /* Physical drive nmuber (0) */\r
+ BYTE *buff, /* Pointer to the data buffer to store read data */\r
+ DWORD sector, /* Start sector number (LBA) */\r
+ BYTE count /* Sector count (1..255) */\r
+ )\r
+{\r
+ if( drv || !count )\r
+ {\r
+ return RES_PARERR;\r
+ }\r
+\r
+ if( Stat & STA_NOINIT )\r
+ {\r
+ return RES_NOTRDY;\r
+ }\r
+\r
+ if( !(CardType & CT_BLOCK) )\r
+ {\r
+ sector *= 512; /* Convert to byte address if needed */\r
+ }\r
+\r
+ if( count == 1 )\r
+ { /* Single block read */\r
+ if( (send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */ && rcvr_datablock(buff, 512) )\r
+ {\r
+ count = 0;\r
+ }\r
+ }\r
+ else\r
+ { /* Multiple block read */\r
+ if( send_cmd(CMD18, sector) == 0 )\r
+ { /* READ_MULTIPLE_BLOCK */\r
+ do\r
+ {\r
+ if( !rcvr_datablock(buff, 512) )\r
+ {\r
+ break;\r
+ }\r
+\r
+ buff += 512;\r
+ } while( --count );\r
+ send_cmd( CMD12, 0 ); /* STOP_TRANSMISSION */\r
+ }\r
+ }\r
+\r
+ deselect();\r
+\r
+ return count ? RES_ERROR : RES_OK;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Write Sector(s) */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+#if _READONLY == 0\r
+DRESULT disk_write\r
+ (\r
+ BYTE drv, /* Physical drive nmuber (0) */\r
+ const BYTE *buff, /* Pointer to the data to be written */\r
+ DWORD sector, /* Start sector number (LBA) */\r
+ BYTE count /* Sector count (1..255) */\r
+ )\r
+{\r
+ if( drv || !count )\r
+ {\r
+ return RES_PARERR;\r
+ }\r
+\r
+ if( Stat & STA_NOINIT )\r
+ {\r
+ return RES_NOTRDY;\r
+ }\r
+\r
+ if( Stat & STA_PROTECT )\r
+ {\r
+ return RES_WRPRT;\r
+ }\r
+\r
+ if( !(CardType & CT_BLOCK) )\r
+ {\r
+ sector *= 512; /* Convert to byte address if needed */\r
+ }\r
+\r
+ if( count == 1 )\r
+ { /* Single block write */\r
+ if( (send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */ && xmit_datablock(buff, 0xFE) )\r
+ {\r
+ count = 0;\r
+ }\r
+ }\r
+ else\r
+ { /* Multiple block write */\r
+ if( CardType & CT_SDC )\r
+ {\r
+ send_cmd( ACMD23, count );\r
+ }\r
+\r
+ if( send_cmd(CMD25, sector) == 0 )\r
+ { /* WRITE_MULTIPLE_BLOCK */\r
+ do\r
+ {\r
+ if( !xmit_datablock(buff, 0xFC) )\r
+ {\r
+ break;\r
+ }\r
+\r
+ buff += 512;\r
+ } while( --count );\r
+ if( !xmit_datablock(0, 0xFD) )\r
+ { /* STOP_TRAN token */\r
+ count = 1;\r
+ }\r
+ }\r
+ }\r
+\r
+ deselect();\r
+\r
+ return count ? RES_ERROR : RES_OK;\r
+}\r
+\r
+#endif /* _READONLY */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Miscellaneous Functions */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+DRESULT disk_ioctl\r
+ (\r
+ BYTE drv, /* Physical drive nmuber (0) */\r
+ BYTE ctrl, /* Control code */\r
+ void *buff /* Buffer to send/receive data block */\r
+ )\r
+{\r
+ DRESULT res;\r
+ BYTE n, csd[16], *ptr = buff;\r
+ DWORD csize;\r
+\r
+ if( drv )\r
+ {\r
+ return RES_PARERR;\r
+ }\r
+\r
+ if( Stat & STA_NOINIT )\r
+ {\r
+ return RES_NOTRDY;\r
+ }\r
+\r
+ res = RES_ERROR;\r
+ switch( ctrl )\r
+ {\r
+ case CTRL_SYNC: /* Flush dirty buffer if present */\r
+ if( select() )\r
+ {\r
+ res = RES_OK;\r
+ deselect();\r
+ }\r
+\r
+ break;\r
+\r
+ case GET_SECTOR_COUNT: /* Get number of sectors on the disk (WORD) */\r
+ if( (send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16) )\r
+ {\r
+ if( (csd[0] >> 6) == 1 )\r
+ { /* SDv2? */\r
+ csize = csd[9] + ( (WORD) csd[8] << 8 ) + 1;\r
+ *( DWORD * ) buff = ( DWORD ) csize << 10;\r
+ }\r
+ else\r
+ { /* SDv1 or MMCv2 */\r
+ n = ( csd[5] & 15 ) + ( (csd[10] & 128) >> 7 ) + ( (csd[9] & 3) << 1 ) + 2;\r
+ csize = ( csd[8] >> 6 ) + ( (WORD) csd[7] << 2 ) + ( (WORD) (csd[6] & 3) << 10 ) + 1;\r
+ *( DWORD * ) buff = ( DWORD ) csize << ( n - 9 );\r
+ }\r
+\r
+ res = RES_OK;\r
+ }\r
+\r
+ break;\r
+\r
+ case GET_SECTOR_SIZE: /* Get sectors on the disk (WORD) */\r
+ * ( WORD * ) buff = 512;\r
+ res = RES_OK;\r
+ break;\r
+\r
+ case GET_BLOCK_SIZE: /* Get erase block size in unit of sectors (DWORD) */\r
+ if( CardType & CT_SD2 )\r
+ { /* SDv2? */\r
+ if( send_cmd(ACMD13, 0) == 0 )\r
+ { /* Read SD status */\r
+ rcvr_spi();\r
+ if( rcvr_datablock(csd, 16) )\r
+ { /* Read partial block */\r
+ for( n = 64 - 16; n; n-- )\r
+ {\r
+ rcvr_spi(); /* Purge trailing data */\r
+ }\r
+\r
+ * ( DWORD * ) buff = 16UL << ( csd[10] >> 4 );\r
+ res = RES_OK;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ { /* SDv1 or MMCv3 */\r
+ if( (send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16) )\r
+ { /* Read CSD */\r
+ if( CardType & CT_SD1 )\r
+ { /* SDv1 */\r
+ *( DWORD * ) buff = ( ((csd[10] & 63) << 1) + ((WORD) (csd[11] & 128) >> 7) + 1 ) << ( (csd[13] >> 6) - 1 );\r
+ }\r
+ else\r
+ { /* MMCv3 */\r
+ *( DWORD * ) buff = ( (WORD) ((csd[10] & 124) >> 2) + 1 ) * ( ((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1 );\r
+ }\r
+\r
+ res = RES_OK;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ case MMC_GET_TYPE: /* Get card type flags (1 byte) */\r
+ *ptr = CardType;\r
+ res = RES_OK;\r
+ break;\r
+\r
+ case MMC_GET_CSD: /* Receive CSD as a data block (16 bytes) */\r
+ if( (send_cmd(CMD9, 0) == 0) /* READ_CSD */ && rcvr_datablock(buff, 16) )\r
+ {\r
+ res = RES_OK;\r
+ }\r
+\r
+ break;\r
+\r
+ case MMC_GET_CID: /* Receive CID as a data block (16 bytes) */\r
+ if( (send_cmd(CMD10, 0) == 0) /* READ_CID */ && rcvr_datablock(buff, 16) )\r
+ {\r
+ res = RES_OK;\r
+ }\r
+\r
+ break;\r
+\r
+ case MMC_GET_OCR: /* Receive OCR as an R3 resp (4 bytes) */\r
+ if( send_cmd(CMD58, 0) == 0 )\r
+ { /* READ_OCR */\r
+ for( n = 0; n < 4; n++ )\r
+ {\r
+ *( ( BYTE * ) buff + n ) = rcvr_spi();\r
+ }\r
+\r
+ res = RES_OK;\r
+ }\r
+\r
+ break;\r
+\r
+ case MMC_GET_SDSTAT: /* Receive SD statsu as a data block (64 bytes) */\r
+ if( send_cmd(ACMD13, 0) == 0 )\r
+ { /* SD_STATUS */\r
+ rcvr_spi();\r
+ if( rcvr_datablock(buff, 64) )\r
+ {\r
+ res = RES_OK;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ default:\r
+ res = RES_PARERR;\r
+ }\r
+\r
+ deselect();\r
+\r
+ return res;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Device Timer Interrupt Procedure (Platform dependent) */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* This function must be called in period of 1ms */\r
+void disk_timerproc( void )\r
+{\r
+ static unsigned long pv;\r
+ unsigned long p;\r
+ BYTE s;\r
+ UINT n;\r
+\r
+ n = Timer1; /* 1000Hz decrement timer */\r
+ if( n )\r
+ {\r
+ Timer1 = --n;\r
+ }\r
+\r
+ n = Timer2;\r
+ if( n )\r
+ {\r
+ Timer2 = --n;\r
+ }\r
+\r
+ p = pv;\r
+ pv = SOCKPORT & ( SOCKWP | SOCKINS ); /* Sample socket switch */\r
+\r
+ if( p == pv )\r
+ { /* Have contacts stabled? */\r
+ s = Stat;\r
+\r
+ if( p & SOCKWP )\r
+ { /* WP is H (write protected) */\r
+ s |= STA_PROTECT;\r
+ }\r
+ else\r
+ { /* WP is L (write enabled) */\r
+ s &= ~STA_PROTECT;\r
+ }\r
+\r
+ if( p & SOCKINS )\r
+ { /* INS = H (Socket empty) */\r
+ s |= ( STA_NODISK | STA_NOINIT );\r
+ }\r
+ else\r
+ { /* INS = L (Card inserted) */\r
+ s &= ~STA_NODISK;\r
+ }\r
+\r
+ Stat = s;\r
+ }\r
+}\r
+\r
+DWORD get_fattime( void )\r
+{\r
+ return 0;\r
+}\r
+\r
+void disk_init_spi( void )\r
+{\r
+ volatile unsigned long ulDummy;\r
+\r
+ /* The SD card is connected using SPI0. Start by enabling power to the\r
+ SPI peripheral. */\r
+ SC->PCONP |= PCONP_PCSPI;\r
+\r
+ /* Also enable the clock to the peripheral. */\r
+ SC->PCLKSEL0 &= ~( 0x03 << 16 );\r
+ SC->PCLKSEL0 |= ( 0x01 << 16 );\r
+\r
+ /* Configure P0.15 as the clock. */\r
+ PINCON->PINSEL0 |= ( 0x03 << 30 );\r
+\r
+ /* Configure P0.16 as SSEL. */\r
+ GPIO0->FIODIR |= ( 0x01 << 16 );\r
+ PINCON->PINSEL1 &= ~( 0x03 );\r
+\r
+ /* Configure P0.17 as MISO. */\r
+ PINCON->PINSEL1 |= ( 0x03 << 2 );\r
+\r
+ /* Configure P0.18 as MOSI. */\r
+ PINCON->PINSEL1 |= ( 0x03 << 4 );\r
+\r
+ /* Configure P4.29 as (presumably) the card detect input. */\r
+ GPIO4->FIODIR &= ~( 1 << 29 );\r
+\r
+ /* Set outputs to outputs... */\r
+ GPIO0->FIODIR |= ( (1 << 15) | (1 << 16) | (1 << 18) );\r
+\r
+ /* ... and inputs to inputs. */\r
+ GPIO0->FIODIR &= ~( 1 << 17 );\r
+\r
+ /* Ensure SSEL is high. */\r
+ CS_HIGH();\r
+\r
+ /* Set SPI to master mode. */\r
+ SPI->SPCR |= ( 1 << 5 );\r
+\r
+ /* Clear all status bits. */\r
+ ulDummy = SPI->SPSR;\r
+\r
+ /* Set the serial clock frequency. 100MHz / 250 = 400KHz. */\r
+ SPI->SPCCR = configCPU_CLOCK_HZ / 250;\r
+}\r
+\r
+\r
--- /dev/null
+/* Based on MMCv3/SDv1/SDv2 (in SPI mode) control module (C)ChaN, 2009 \r
+Modifications (C) 2010 Real Time Engineers ltd. */\r
+\r
+#include "FreeRTOS.h"\r
+#include "diskio.h"\r
+\r
+void disk_init_spi( void );\r
+\r
+/* Definitions for MMC/SDC command */\r
+#define CMD0 ( 0x40 + 0 ) /* GO_IDLE_STATE */\r
+#define CMD1 ( 0x40 + 1 ) /* SEND_OP_COND (MMC) */\r
+#define ACMD41 ( 0xC0 + 41 ) /* SEND_OP_COND (SDC) */\r
+#define CMD8 ( 0x40 + 8 ) /* SEND_IF_COND */\r
+#define CMD9 ( 0x40 + 9 ) /* SEND_CSD */\r
+#define CMD10 ( 0x40 + 10 ) /* SEND_CID */\r
+#define CMD12 ( 0x40 + 12 ) /* STOP_TRANSMISSION */\r
+#define ACMD13 ( 0xC0 + 13 ) /* SD_STATUS (SDC) */\r
+#define CMD16 ( 0x40 + 16 ) /* SET_BLOCKLEN */\r
+#define CMD17 ( 0x40 + 17 ) /* READ_SINGLE_BLOCK */\r
+#define CMD18 ( 0x40 + 18 ) /* READ_MULTIPLE_BLOCK */\r
+#define CMD23 ( 0x40 + 23 ) /* SET_BLOCK_COUNT (MMC) */\r
+#define ACMD23 ( 0xC0 + 23 ) /* SET_WR_BLK_ERASE_COUNT (SDC) */\r
+#define CMD24 ( 0x40 + 24 ) /* WRITE_BLOCK */\r
+#define CMD25 ( 0x40 + 25 ) /* WRITE_MULTIPLE_BLOCK */\r
+#define CMD55 ( 0x40 + 55 ) /* APP_CMD */\r
+#define CMD58 ( 0x40 + 58 ) /* READ_OCR */\r
+\r
+/* Port Controls (Platform dependent) */\r
+#define CS_LOW() GPIO0->FIOCLR = ( 1 << 16 ) /* MMC CS = L */\r
+#define CS_HIGH() GPIO0->FIOSET = ( 1 << 16 ) /* MMC CS = H */\r
+\r
+#define SOCKWP ( 0 ) /* Write protect switch. */\r
+#define SOCKINS ( 1 << 29 ) /* Card detect switch. */\r
+#define SOCKPORT ( GPIO4->FIOPIN )\r
+#define FCLK_SLOW() /* Set slow clock (100k-400k) */\r
+#define FCLK_FAST() /* Set fast clock (depends on the CSD) */\r
+\r
+#define xmit_spi( dat ) xchg_spi( dat )\r
+#define rcvr_spi() xchg_spi( 0xFF )\r
+#define rcvr_spi_m( p ) \\r
+ SPI->SPDR = 0xFF; \\r
+ while( !( SPI->SPSR & ( 1 << 7 ) ) ); /* Check SPIF bit. */ \\r
+ *( p ) = ( BYTE ) SPI->SPDR;\r
+\r
+/*-------------------------------------------------------------------------- */\r
+\r
+static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */\r
+static volatile UINT Timer1, Timer2; /* 1000Hz decrement timer */\r
+static UINT CardType;\r
+\r
+static BYTE xchg_spi( BYTE dat )\r
+{\r
+ SPI->SPDR = dat;\r
+ while( !( SPI->SPSR & ( 1 << 7 ) ) ); /* Check SPIF bit. */\r
+ return( BYTE ) SPI->SPDR;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Wait for card ready */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+static BYTE wait_ready( void )\r
+{\r
+ BYTE res;\r
+\r
+ Timer2 = 500; /* Wait for ready in timeout of 500ms */\r
+ rcvr_spi();\r
+ do\r
+ {\r
+ res = rcvr_spi();\r
+ } while( (res != 0xFF) && Timer2 );\r
+\r
+ return res;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Deselect the card and release SPI bus */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+static void deselect( void )\r
+{\r
+ CS_HIGH();\r
+ rcvr_spi();\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Select the card and wait ready */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+static BOOL select( void ) /* TRUE:Successful, FALSE:Timeout */\r
+{\r
+ CS_LOW();\r
+ if( wait_ready() != 0xFF )\r
+ {\r
+ deselect();\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Power Control (Platform dependent) */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* When the target system does not support socket power control, there */\r
+\r
+/* is nothing to do in these functions and chk_power always returns 1. */\r
+static void power_on( void )\r
+{\r
+#if 0\r
+ /* Enable SPI1 */\r
+ SPI1CON1 = 0x013B;\r
+ SPI1CON2 = 0x0000;\r
+ _SPIEN = 1;\r
+#endif\r
+}\r
+\r
+static void power_off( void )\r
+{\r
+#if 0\r
+ select(); /* Wait for card ready */\r
+ deselect();\r
+\r
+ _SPIEN = 0; /* Disable SPI1 */\r
+\r
+ Stat |= STA_NOINIT; /* Set STA_NOINIT */\r
+#endif\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Receive a data packet from MMC */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+static BOOL rcvr_datablock( BYTE *buff, /* Data buffer to store received data */ UINT btr /* Byte count (must be multiple of 4) */ )\r
+{\r
+ BYTE token;\r
+\r
+ Timer1 = 100;\r
+ do\r
+ { /* Wait for data packet in timeout of 100ms */\r
+ token = rcvr_spi();\r
+ } while( (token == 0xFF) && Timer1 );\r
+\r
+ if( token != 0xFE )\r
+ {\r
+ return FALSE; /* If not valid data token, retutn with error */\r
+ }\r
+\r
+ do\r
+ { /* Receive the data block into buffer */\r
+ rcvr_spi_m( buff++ );\r
+ rcvr_spi_m( buff++ );\r
+ rcvr_spi_m( buff++ );\r
+ rcvr_spi_m( buff++ );\r
+ } while( btr -= 4 );\r
+ rcvr_spi(); /* Discard CRC */\r
+ rcvr_spi();\r
+\r
+ return TRUE; /* Return with success */\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Send a data packet to MMC */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+#if _READONLY == 0\r
+static BOOL xmit_datablock( const BYTE *buff, /* 512 byte data block to be transmitted */ BYTE token /* Data/Stop token */ )\r
+{\r
+ BYTE resp;\r
+ UINT bc = 512;\r
+\r
+ if( wait_ready() != 0xFF )\r
+ {\r
+ return FALSE;\r
+ }\r
+\r
+ xmit_spi( token ); /* Xmit data token */\r
+ if( token != 0xFD )\r
+ { /* Is data token */\r
+ do\r
+ { /* Xmit the 512 byte data block to MMC */\r
+ xmit_spi( *buff++ );\r
+ xmit_spi( *buff++ );\r
+ } while( bc -= 2 );\r
+ xmit_spi( 0xFF ); /* CRC (Dummy) */\r
+ xmit_spi( 0xFF );\r
+ resp = rcvr_spi(); /* Receive data response */\r
+ if( (resp & 0x1F) != 0x05 )\r
+ { /* If not accepted, return with error */\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+#endif /* _READONLY */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Send a command packet to MMC */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+static BYTE send_cmd( BYTE cmd, /* Command byte */ DWORD arg /* Argument */ )\r
+{\r
+ BYTE n, res;\r
+\r
+ if( cmd & 0x80 )\r
+ { /* ACMD<n> is the command sequense of CMD55-CMD<n> */\r
+ cmd &= 0x7F;\r
+ res = send_cmd( CMD55, 0 );\r
+ if( res > 1 )\r
+ {\r
+ return res;\r
+ }\r
+ }\r
+\r
+ /* Select the card and wait for ready */\r
+ deselect();\r
+ if( !select() )\r
+ {\r
+ return 0xFF;\r
+ }\r
+\r
+ /* Send command packet */\r
+ xmit_spi( cmd ); /* Start + Command index */\r
+ xmit_spi( (BYTE) (arg >> 24) ); /* Argument[31..24] */\r
+ xmit_spi( (BYTE) (arg >> 16) ); /* Argument[23..16] */\r
+ xmit_spi( (BYTE) (arg >> 8) ); /* Argument[15..8] */\r
+ xmit_spi( (BYTE) arg ); /* Argument[7..0] */\r
+ n = 0x01; /* Dummy CRC + Stop */\r
+ if( cmd == CMD0 )\r
+ {\r
+ n = 0x95; /* Valid CRC for CMD0(0) */\r
+ }\r
+\r
+ if( cmd == CMD8 )\r
+ {\r
+ n = 0x87; /* Valid CRC for CMD8(0x1AA) */\r
+ }\r
+\r
+ xmit_spi( n );\r
+\r
+ /* Receive command response */\r
+ if( cmd == CMD12 )\r
+ {\r
+ rcvr_spi(); /* Skip a stuff byte when stop reading */\r
+ }\r
+\r
+ n = 10; /* Wait for a valid response in timeout of 10 attempts */\r
+ do\r
+ {\r
+ res = rcvr_spi();\r
+ } while( (res & 0x80) && --n );\r
+\r
+ return res; /* Return with the response value */\r
+}\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Public Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Initialize Disk Drive */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+DSTATUS disk_initialize( BYTE drv /* Physical drive nmuber (0) */ )\r
+{\r
+ BYTE n, cmd, ty, ocr[4];\r
+\r
+ if( drv )\r
+ {\r
+ return STA_NOINIT; /* Supports only single drive */\r
+ }\r
+\r
+ if( Stat & STA_NODISK )\r
+ {\r
+ return Stat; /* No card in the socket */\r
+ }\r
+\r
+ power_on(); /* Force socket power on */\r
+ FCLK_SLOW();\r
+ for( n = 10; n; n-- )\r
+ {\r
+ rcvr_spi(); /* 80 dummy clocks */\r
+ }\r
+\r
+ ty = 0;\r
+ if( send_cmd(CMD0, 0) == 1 )\r
+ { /* Enter Idle state */\r
+ Timer1 = 1000; /* Initialization timeout of 1000 msec */\r
+ if( send_cmd(CMD8, 0x1AA) == 1 )\r
+ { /* SDv2? */\r
+ for( n = 0; n < 4; n++ )\r
+ {\r
+ ocr[n] = rcvr_spi(); /* Get trailing return value of R7 resp */\r
+ }\r
+\r
+ if( ocr[2] == 0x01 && ocr[3] == 0xAA )\r
+ { /* The card can work at vdd range of 2.7-3.6V */\r
+ while( Timer1 && send_cmd(ACMD41, 1UL << 30) );\r
+\r
+ /* Wait for leaving idle state (ACMD41 with HCS bit) */\r
+ if( Timer1 && send_cmd(CMD58, 0) == 0 )\r
+ { /* Check CCS bit in the OCR */\r
+ for( n = 0; n < 4; n++ )\r
+ {\r
+ ocr[n] = rcvr_spi();\r
+ }\r
+\r
+ ty = ( ocr[0] & 0x40 ) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC/SC) */\r
+ }\r
+ }\r
+ }\r
+ else\r
+ { /* SDv1 or MMCv3 */\r
+ if( send_cmd(ACMD41, 0) <= 1 )\r
+ {\r
+ ty = CT_SD1;\r
+ cmd = ACMD41; /* SDv1 */\r
+ }\r
+ else\r
+ {\r
+ ty = CT_MMC;\r
+ cmd = CMD1; /* MMCv3 */\r
+ }\r
+\r
+ while( Timer1 && send_cmd(cmd, 0) );\r
+\r
+ /* Wait for leaving idle state */\r
+ if( !Timer1 || send_cmd(CMD16, 512) != 0 )\r
+ { /* Set R/W block length to 512 */\r
+ ty = 0;\r
+ }\r
+ }\r
+ }\r
+\r
+ CardType = ty;\r
+ deselect();\r
+\r
+ if( ty )\r
+ { /* Initialization succeded */\r
+ Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */\r
+ FCLK_FAST();\r
+ }\r
+ else\r
+ { /* Initialization failed */\r
+ power_off();\r
+ }\r
+\r
+ return Stat;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Get Disk Status */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+DSTATUS disk_status( BYTE drv /* Physical drive nmuber (0) */ )\r
+{\r
+ if( drv )\r
+ {\r
+ return STA_NOINIT; /* Supports only single drive */\r
+ }\r
+\r
+ return Stat;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Read Sector(s) */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+DRESULT disk_read\r
+ (\r
+ BYTE drv, /* Physical drive nmuber (0) */\r
+ BYTE *buff, /* Pointer to the data buffer to store read data */\r
+ DWORD sector, /* Start sector number (LBA) */\r
+ BYTE count /* Sector count (1..255) */\r
+ )\r
+{\r
+ if( drv || !count )\r
+ {\r
+ return RES_PARERR;\r
+ }\r
+\r
+ if( Stat & STA_NOINIT )\r
+ {\r
+ return RES_NOTRDY;\r
+ }\r
+\r
+ if( !(CardType & CT_BLOCK) )\r
+ {\r
+ sector *= 512; /* Convert to byte address if needed */\r
+ }\r
+\r
+ if( count == 1 )\r
+ { /* Single block read */\r
+ if( (send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */ && rcvr_datablock(buff, 512) )\r
+ {\r
+ count = 0;\r
+ }\r
+ }\r
+ else\r
+ { /* Multiple block read */\r
+ if( send_cmd(CMD18, sector) == 0 )\r
+ { /* READ_MULTIPLE_BLOCK */\r
+ do\r
+ {\r
+ if( !rcvr_datablock(buff, 512) )\r
+ {\r
+ break;\r
+ }\r
+\r
+ buff += 512;\r
+ } while( --count );\r
+ send_cmd( CMD12, 0 ); /* STOP_TRANSMISSION */\r
+ }\r
+ }\r
+\r
+ deselect();\r
+\r
+ return count ? RES_ERROR : RES_OK;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Write Sector(s) */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+#if _READONLY == 0\r
+DRESULT disk_write\r
+ (\r
+ BYTE drv, /* Physical drive nmuber (0) */\r
+ const BYTE *buff, /* Pointer to the data to be written */\r
+ DWORD sector, /* Start sector number (LBA) */\r
+ BYTE count /* Sector count (1..255) */\r
+ )\r
+{\r
+ if( drv || !count )\r
+ {\r
+ return RES_PARERR;\r
+ }\r
+\r
+ if( Stat & STA_NOINIT )\r
+ {\r
+ return RES_NOTRDY;\r
+ }\r
+\r
+ if( Stat & STA_PROTECT )\r
+ {\r
+ return RES_WRPRT;\r
+ }\r
+\r
+ if( !(CardType & CT_BLOCK) )\r
+ {\r
+ sector *= 512; /* Convert to byte address if needed */\r
+ }\r
+\r
+ if( count == 1 )\r
+ { /* Single block write */\r
+ if( (send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */ && xmit_datablock(buff, 0xFE) )\r
+ {\r
+ count = 0;\r
+ }\r
+ }\r
+ else\r
+ { /* Multiple block write */\r
+ if( CardType & CT_SDC )\r
+ {\r
+ send_cmd( ACMD23, count );\r
+ }\r
+\r
+ if( send_cmd(CMD25, sector) == 0 )\r
+ { /* WRITE_MULTIPLE_BLOCK */\r
+ do\r
+ {\r
+ if( !xmit_datablock(buff, 0xFC) )\r
+ {\r
+ break;\r
+ }\r
+\r
+ buff += 512;\r
+ } while( --count );\r
+ if( !xmit_datablock(0, 0xFD) )\r
+ { /* STOP_TRAN token */\r
+ count = 1;\r
+ }\r
+ }\r
+ }\r
+\r
+ deselect();\r
+\r
+ return count ? RES_ERROR : RES_OK;\r
+}\r
+\r
+#endif /* _READONLY */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Miscellaneous Functions */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+DRESULT disk_ioctl\r
+ (\r
+ BYTE drv, /* Physical drive nmuber (0) */\r
+ BYTE ctrl, /* Control code */\r
+ void *buff /* Buffer to send/receive data block */\r
+ )\r
+{\r
+ DRESULT res;\r
+ BYTE n, csd[16], *ptr = buff;\r
+ DWORD csize;\r
+\r
+ if( drv )\r
+ {\r
+ return RES_PARERR;\r
+ }\r
+\r
+ if( Stat & STA_NOINIT )\r
+ {\r
+ return RES_NOTRDY;\r
+ }\r
+\r
+ res = RES_ERROR;\r
+ switch( ctrl )\r
+ {\r
+ case CTRL_SYNC: /* Flush dirty buffer if present */\r
+ if( select() )\r
+ {\r
+ res = RES_OK;\r
+ deselect();\r
+ }\r
+\r
+ break;\r
+\r
+ case GET_SECTOR_COUNT: /* Get number of sectors on the disk (WORD) */\r
+ if( (send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16) )\r
+ {\r
+ if( (csd[0] >> 6) == 1 )\r
+ { /* SDv2? */\r
+ csize = csd[9] + ( (WORD) csd[8] << 8 ) + 1;\r
+ *( DWORD * ) buff = ( DWORD ) csize << 10;\r
+ }\r
+ else\r
+ { /* SDv1 or MMCv2 */\r
+ n = ( csd[5] & 15 ) + ( (csd[10] & 128) >> 7 ) + ( (csd[9] & 3) << 1 ) + 2;\r
+ csize = ( csd[8] >> 6 ) + ( (WORD) csd[7] << 2 ) + ( (WORD) (csd[6] & 3) << 10 ) + 1;\r
+ *( DWORD * ) buff = ( DWORD ) csize << ( n - 9 );\r
+ }\r
+\r
+ res = RES_OK;\r
+ }\r
+\r
+ break;\r
+\r
+ case GET_SECTOR_SIZE: /* Get sectors on the disk (WORD) */\r
+ * ( WORD * ) buff = 512;\r
+ res = RES_OK;\r
+ break;\r
+\r
+ case GET_BLOCK_SIZE: /* Get erase block size in unit of sectors (DWORD) */\r
+ if( CardType & CT_SD2 )\r
+ { /* SDv2? */\r
+ if( send_cmd(ACMD13, 0) == 0 )\r
+ { /* Read SD status */\r
+ rcvr_spi();\r
+ if( rcvr_datablock(csd, 16) )\r
+ { /* Read partial block */\r
+ for( n = 64 - 16; n; n-- )\r
+ {\r
+ rcvr_spi(); /* Purge trailing data */\r
+ }\r
+\r
+ * ( DWORD * ) buff = 16UL << ( csd[10] >> 4 );\r
+ res = RES_OK;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ { /* SDv1 or MMCv3 */\r
+ if( (send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16) )\r
+ { /* Read CSD */\r
+ if( CardType & CT_SD1 )\r
+ { /* SDv1 */\r
+ *( DWORD * ) buff = ( ((csd[10] & 63) << 1) + ((WORD) (csd[11] & 128) >> 7) + 1 ) << ( (csd[13] >> 6) - 1 );\r
+ }\r
+ else\r
+ { /* MMCv3 */\r
+ *( DWORD * ) buff = ( (WORD) ((csd[10] & 124) >> 2) + 1 ) * ( ((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1 );\r
+ }\r
+\r
+ res = RES_OK;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ case MMC_GET_TYPE: /* Get card type flags (1 byte) */\r
+ *ptr = CardType;\r
+ res = RES_OK;\r
+ break;\r
+\r
+ case MMC_GET_CSD: /* Receive CSD as a data block (16 bytes) */\r
+ if( (send_cmd(CMD9, 0) == 0) /* READ_CSD */ && rcvr_datablock(buff, 16) )\r
+ {\r
+ res = RES_OK;\r
+ }\r
+\r
+ break;\r
+\r
+ case MMC_GET_CID: /* Receive CID as a data block (16 bytes) */\r
+ if( (send_cmd(CMD10, 0) == 0) /* READ_CID */ && rcvr_datablock(buff, 16) )\r
+ {\r
+ res = RES_OK;\r
+ }\r
+\r
+ break;\r
+\r
+ case MMC_GET_OCR: /* Receive OCR as an R3 resp (4 bytes) */\r
+ if( send_cmd(CMD58, 0) == 0 )\r
+ { /* READ_OCR */\r
+ for( n = 0; n < 4; n++ )\r
+ {\r
+ *( ( BYTE * ) buff + n ) = rcvr_spi();\r
+ }\r
+\r
+ res = RES_OK;\r
+ }\r
+\r
+ break;\r
+\r
+ case MMC_GET_SDSTAT: /* Receive SD statsu as a data block (64 bytes) */\r
+ if( send_cmd(ACMD13, 0) == 0 )\r
+ { /* SD_STATUS */\r
+ rcvr_spi();\r
+ if( rcvr_datablock(buff, 64) )\r
+ {\r
+ res = RES_OK;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ default:\r
+ res = RES_PARERR;\r
+ }\r
+\r
+ deselect();\r
+\r
+ return res;\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Device Timer Interrupt Procedure (Platform dependent) */\r
+\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* This function must be called in period of 1ms */\r
+void disk_timerproc( void )\r
+{\r
+ static unsigned long pv;\r
+ unsigned long p;\r
+ BYTE s;\r
+ UINT n;\r
+\r
+ n = Timer1; /* 1000Hz decrement timer */\r
+ if( n )\r
+ {\r
+ Timer1 = --n;\r
+ }\r
+\r
+ n = Timer2;\r
+ if( n )\r
+ {\r
+ Timer2 = --n;\r
+ }\r
+\r
+ p = pv;\r
+ pv = SOCKPORT & ( SOCKWP | SOCKINS ); /* Sample socket switch */\r
+\r
+ if( p == pv )\r
+ { /* Have contacts stabled? */\r
+ s = Stat;\r
+\r
+ if( p & SOCKWP )\r
+ { /* WP is H (write protected) */\r
+ s |= STA_PROTECT;\r
+ }\r
+ else\r
+ { /* WP is L (write enabled) */\r
+ s &= ~STA_PROTECT;\r
+ }\r
+\r
+ if( p & SOCKINS )\r
+ { /* INS = H (Socket empty) */\r
+ s |= ( STA_NODISK | STA_NOINIT );\r
+ }\r
+ else\r
+ { /* INS = L (Card inserted) */\r
+ s &= ~STA_NODISK;\r
+ }\r
+\r
+ Stat = s;\r
+ }\r
+}\r
+\r
+DWORD get_fattime( void )\r
+{\r
+ return 0;\r
+}\r
+\r
+void disk_init_spi( void )\r
+{\r
+ volatile unsigned long ulDummy;\r
+\r
+ /* The SD card is connected using SPI0. Start by enabling power to the\r
+ SPI peripheral. */\r
+ SC->PCONP |= PCONP_PCSPI;\r
+\r
+ /* Also enable the clock to the peripheral. */\r
+ SC->PCLKSEL0 &= ~( 0x03 << 16 );\r
+ SC->PCLKSEL0 |= ( 0x01 << 16 );\r
+\r
+ /* Configure P0.15 as the clock. */\r
+ PINCON->PINSEL0 |= ( 0x03 << 30 );\r
+\r
+ /* Configure P0.16 as SSEL. */\r
+ GPIO0->FIODIR |= ( 0x01 << 16 );\r
+ PINCON->PINSEL1 &= ~( 0x03 );\r
+\r
+ /* Configure P0.17 as MISO. */\r
+ PINCON->PINSEL1 |= ( 0x03 << 2 );\r
+\r
+ /* Configure P0.18 as MOSI. */\r
+ PINCON->PINSEL1 |= ( 0x03 << 4 );\r
+\r
+ /* Configure P4.29 as (presumably) the card detect input. */\r
+// GPIO4->FIODIR &= ~( 1 << 29 );\r
+\r
+ /* Set outputs to outputs... */\r
+ GPIO0->FIODIR |= ( (1 << 15) | (1 << 16) | (1 << 18) );\r
+\r
+ /* ... and inputs to inputs. */\r
+ GPIO0->FIODIR &= ~( 1 << 17 );\r
+\r
+ /* Ensure SSEL is high. */\r
+ CS_HIGH();\r
+\r
+ /* Set SPI to master mode. */\r
+ SPI->SPCR |= ( 1 << 5 );\r
+\r
+ /* Clear all status bits. */\r
+ ulDummy = SPI->SPSR;\r
+\r
+ /* Set the serial clock frequency. 100MHz / 250 = 400KHz. */\r
+ SPI->SPCCR = configCPU_CLOCK_HZ / 250;\r
+}\r
+\r
+\r
--- /dev/null
+/*-----------------------------------------------------------------------\r
+/ Low level disk interface modlue include file R0.07 (C)ChaN, 2009\r
+/-----------------------------------------------------------------------*/\r
+\r
+#ifndef _DISKIO\r
+\r
+#define _READONLY 0 /* 1: Read-only mode */\r
+#define _USE_IOCTL 1\r
+\r
+#include "fat_integer.h"\r
+\r
+\r
+/* Status of Disk Functions */\r
+typedef BYTE DSTATUS;\r
+\r
+/* Results of Disk Functions */\r
+typedef enum {\r
+ RES_OK = 0, /* 0: Successful */\r
+ RES_ERROR, /* 1: R/W Error */\r
+ RES_WRPRT, /* 2: Write Protected */\r
+ RES_NOTRDY, /* 3: Not Ready */\r
+ RES_PARERR /* 4: Invalid Parameter */\r
+} DRESULT;\r
+\r
+\r
+/*---------------------------------------*/\r
+/* Prototypes for disk control functions */\r
+\r
+void disk_init_spi( void );\r
+BOOL assign_drives (int argc, char *argv[]);\r
+DSTATUS disk_initialize (BYTE);\r
+DSTATUS disk_status (BYTE);\r
+DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);\r
+#if _READONLY == 0\r
+DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);\r
+#endif\r
+DRESULT disk_ioctl (BYTE, BYTE, void*);\r
+\r
+\r
+\r
+/* Disk Status Bits (DSTATUS) */\r
+\r
+#define STA_NOINIT 0x01 /* Drive not initialized */\r
+#define STA_NODISK 0x02 /* No medium in the drive */\r
+#define STA_PROTECT 0x04 /* Write protected */\r
+\r
+\r
+/* Command code for disk_ioctrl() */\r
+\r
+/* Generic command */\r
+#define CTRL_SYNC 0 /* Mandatory for write functions */\r
+#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */\r
+#define GET_SECTOR_SIZE 2 /* Mandatory for multiple sector size cfg */\r
+#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */\r
+#define CTRL_POWER 4\r
+#define CTRL_LOCK 5\r
+#define CTRL_EJECT 6\r
+/* MMC/SDC command */\r
+#define MMC_GET_TYPE 10\r
+#define MMC_GET_CSD 11\r
+#define MMC_GET_CID 12\r
+#define MMC_GET_OCR 13\r
+#define MMC_GET_SDSTAT 14\r
+/* ATA/CF command */\r
+#define ATA_GET_REV 20\r
+#define ATA_GET_MODEL 21\r
+#define ATA_GET_SN 22\r
+\r
+/* Card type definitions (CardType) */\r
+\r
+#define CT_MMC 0x01\r
+#define CT_SD1 0x02\r
+#define CT_SD2 0x04\r
+#define CT_SDC (CT_SD1|CT_SD2)\r
+#define CT_BLOCK 0x08\r
+\r
+#define _DISKIO\r
+#endif\r
--- /dev/null
+/*-----------------------------------------------------------------------\r
+/ Low level disk interface modlue include file R0.07 (C)ChaN, 2009\r
+/-----------------------------------------------------------------------*/\r
+\r
+#ifndef _DISKIO\r
+\r
+#define _READONLY 0 /* 1: Read-only mode */\r
+#define _USE_IOCTL 1\r
+\r
+#include "fat_integer.h"\r
+\r
+\r
+/* Status of Disk Functions */\r
+typedef BYTE DSTATUS;\r
+\r
+/* Results of Disk Functions */\r
+typedef enum {\r
+ RES_OK = 0, /* 0: Successful */\r
+ RES_ERROR, /* 1: R/W Error */\r
+ RES_WRPRT, /* 2: Write Protected */\r
+ RES_NOTRDY, /* 3: Not Ready */\r
+ RES_PARERR /* 4: Invalid Parameter */\r
+} DRESULT;\r
+\r
+\r
+/*---------------------------------------*/\r
+/* Prototypes for disk control functions */\r
+\r
+BOOL assign_drives (int argc, char *argv[]);\r
+DSTATUS disk_initialize (BYTE);\r
+DSTATUS disk_status (BYTE);\r
+DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);\r
+#if _READONLY == 0\r
+DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);\r
+#endif\r
+DRESULT disk_ioctl (BYTE, BYTE, void*);\r
+\r
+\r
+\r
+/* Disk Status Bits (DSTATUS) */\r
+\r
+#define STA_NOINIT 0x01 /* Drive not initialized */\r
+#define STA_NODISK 0x02 /* No medium in the drive */\r
+#define STA_PROTECT 0x04 /* Write protected */\r
+\r
+\r
+/* Command code for disk_ioctrl() */\r
+\r
+/* Generic command */\r
+#define CTRL_SYNC 0 /* Mandatory for write functions */\r
+#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */\r
+#define GET_SECTOR_SIZE 2 /* Mandatory for multiple sector size cfg */\r
+#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */\r
+#define CTRL_POWER 4\r
+#define CTRL_LOCK 5\r
+#define CTRL_EJECT 6\r
+/* MMC/SDC command */\r
+#define MMC_GET_TYPE 10\r
+#define MMC_GET_CSD 11\r
+#define MMC_GET_CID 12\r
+#define MMC_GET_OCR 13\r
+#define MMC_GET_SDSTAT 14\r
+/* ATA/CF command */\r
+#define ATA_GET_REV 20\r
+#define ATA_GET_MODEL 21\r
+#define ATA_GET_SN 22\r
+\r
+/* Card type definitions (CardType) */\r
+\r
+#define CT_MMC 0x01\r
+#define CT_SD1 0x02\r
+#define CT_SD2 0x04\r
+#define CT_SDC (CT_SD1|CT_SD2)\r
+#define CT_BLOCK 0x08\r
+\r
+#define _DISKIO\r
+#endif\r
--- /dev/null
+/*---------------------------------------------------------------------------/\r
+/ FatFs - FAT file system module configuration file R0.07e (C)ChaN, 2009\r
+/----------------------------------------------------------------------------/\r
+/\r
+/ CAUTION! Do not forget to make clean the project after any changes to\r
+/ the configuration options.\r
+/\r
+/----------------------------------------------------------------------------*/\r
+#ifndef _FFCONFIG\r
+#define _FFCONFIG 0x007E\r
+\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ Function and Buffer Configurations\r
+/----------------------------------------------------------------------------*/\r
+\r
+#define _FS_TINY 0 /* 0 or 1 */\r
+/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system\r
+/ object instead of the sector buffer in the individual file object for file\r
+/ data transfer. This reduces memory consumption 512 bytes each file object. */\r
+\r
+\r
+#define _FS_READONLY 0 /* 0 or 1 */\r
+/* Setting _FS_READONLY to 1 defines read only configuration. This removes\r
+/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,\r
+/ f_truncate and useless f_getfree. */\r
+\r
+\r
+#define _FS_MINIMIZE 0 /* 0, 1, 2 or 3 */\r
+/* The _FS_MINIMIZE option defines minimization level to remove some functions.\r
+/\r
+/ 0: Full function.\r
+/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename\r
+/ are removed.\r
+/ 2: f_opendir and f_readdir are removed in addition to level 1.\r
+/ 3: f_lseek is removed in addition to level 2. */\r
+\r
+\r
+#define _USE_STRFUNC 0 /* 0, 1 or 2 */\r
+/* To enable string functions, set _USE_STRFUNC to 1 or 2. */\r
+\r
+\r
+#define _USE_MKFS 0 /* 0 or 1 */\r
+/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */\r
+\r
+\r
+#define _USE_FORWARD 0 /* 0 or 1 */\r
+/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */\r
+\r
+\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ Locale and Namespace Configurations\r
+/----------------------------------------------------------------------------*/\r
+\r
+#define _CODE_PAGE 437\r
+/* The _CODE_PAGE specifies the OEM code page to be used on the target system.\r
+/ Incorrect setting of the code page can cause a file open failure.\r
+/\r
+/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)\r
+/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)\r
+/ 949 - Korean (DBCS, OEM, Windows)\r
+/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)\r
+/ 1250 - Central Europe (Windows)\r
+/ 1251 - Cyrillic (Windows)\r
+/ 1252 - Latin 1 (Windows)\r
+/ 1253 - Greek (Windows)\r
+/ 1254 - Turkish (Windows)\r
+/ 1255 - Hebrew (Windows)\r
+/ 1256 - Arabic (Windows)\r
+/ 1257 - Baltic (Windows)\r
+/ 1258 - Vietnam (OEM, Windows)\r
+/ 437 - U.S. (OEM)\r
+/ 720 - Arabic (OEM)\r
+/ 737 - Greek (OEM)\r
+/ 775 - Baltic (OEM)\r
+/ 850 - Multilingual Latin 1 (OEM)\r
+/ 858 - Multilingual Latin 1 + Euro (OEM)\r
+/ 852 - Latin 2 (OEM)\r
+/ 855 - Cyrillic (OEM)\r
+/ 866 - Russian (OEM)\r
+/ 857 - Turkish (OEM)\r
+/ 862 - Hebrew (OEM)\r
+/ 874 - Thai (OEM, Windows)\r
+/ 1 - ASCII only (Valid for non LFN cfg.)\r
+*/\r
+\r
+\r
+#define _USE_LFN 0 /* 0, 1 or 2 */\r
+#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */\r
+/* The _USE_LFN option switches the LFN support.\r
+/\r
+/ 0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect.\r
+/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT.\r
+/ 2: Enable LFN with dynamic working buffer on the STACK.\r
+/\r
+/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN,\r
+/ two Unicode handling functions ff_convert() and ff_wtoupper() must be added\r
+/ to the project. */\r
+\r
+\r
+#define _LFN_UNICODE 0 /* 0 or 1 */\r
+/* To switch the character code set on FatFs API to Unicode,\r
+/ enable LFN feature and set _LFN_UNICODE to 1.\r
+*/\r
+\r
+\r
+#define _FS_RPATH 0 /* 0 or 1 */\r
+/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir,\r
+/ f_chdrive function are available.\r
+/ Note that output of the f_readdir fnction is affected by this option. */\r
+\r
+\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ Physical Drive Configurations\r
+/----------------------------------------------------------------------------*/\r
+\r
+#define _DRIVES 1\r
+/* Number of volumes (logical drives) to be used. */\r
+\r
+\r
+#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */\r
+/* Maximum sector size to be handled.\r
+/ Always set 512 for memory card and hard disk but a larger value may be\r
+/ required for floppy disk (512/1024) and optical disk (512/2048).\r
+/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted\r
+/ to the disk_ioctl function. */\r
+\r
+\r
+#define _MULTI_PARTITION 0 /* 0 or 1 */\r
+/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical\r
+/ drive number and can mount only first primaly partition. When it is set to 1,\r
+/ each volume is tied to the partitions listed in Drives[]. */\r
+\r
+\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ System Configurations\r
+/----------------------------------------------------------------------------*/\r
+\r
+#define _WORD_ACCESS 0 /* 0 or 1 */\r
+/* The _WORD_ACCESS option defines which access method is used to the word\r
+/ data on the FAT volume.\r
+/\r
+/ 0: Byte-by-byte access. Always compatible with all platforms.\r
+/ 1: Word access. Do not choose this unless following condition is met.\r
+/\r
+/ When the byte order on the memory is big-endian or address miss-aligned\r
+/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.\r
+/ If it is not the case, the value can also be set to 1 to improve the\r
+/ performance and code size. */\r
+\r
+\r
+#define _FS_REENTRANT 1 /* 0 or 1 */\r
+#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */\r
+#define _SYNC_t void * /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */\r
+/* The _FS_REENTRANT option switches the reentrancy of the FatFs module.\r
+/\r
+/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.\r
+/ 1: Enable reentrancy. Also user provided synchronization handlers,\r
+/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj\r
+/ function must be added to the project. */\r
+\r
+\r
+#endif /* _FFCONFIG */\r
--- /dev/null
+/*---------------------------------------------------------------------------/\r
+/ FatFs - FAT file system module configuration file R0.07e (C)ChaN, 2009\r
+/----------------------------------------------------------------------------/\r
+/\r
+/ CAUTION! Do not forget to make clean the project after any changes to\r
+/ the configuration options.\r
+/\r
+/----------------------------------------------------------------------------*/\r
+#ifndef _FFCONFIG\r
+#define _FFCONFIG 0x007E\r
+\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ Function and Buffer Configurations\r
+/----------------------------------------------------------------------------*/\r
+\r
+#define _FS_TINY 0 /* 0 or 1 */\r
+/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system\r
+/ object instead of the sector buffer in the individual file object for file\r
+/ data transfer. This reduces memory consumption 512 bytes each file object. */\r
+\r
+\r
+#define _FS_READONLY 0 /* 0 or 1 */\r
+/* Setting _FS_READONLY to 1 defines read only configuration. This removes\r
+/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,\r
+/ f_truncate and useless f_getfree. */\r
+\r
+\r
+#define _FS_MINIMIZE 0 /* 0, 1, 2 or 3 */\r
+/* The _FS_MINIMIZE option defines minimization level to remove some functions.\r
+/\r
+/ 0: Full function.\r
+/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename\r
+/ are removed.\r
+/ 2: f_opendir and f_readdir are removed in addition to level 1.\r
+/ 3: f_lseek is removed in addition to level 2. */\r
+\r
+\r
+#define _USE_STRFUNC 0 /* 0, 1 or 2 */\r
+/* To enable string functions, set _USE_STRFUNC to 1 or 2. */\r
+\r
+\r
+#define _USE_MKFS 0 /* 0 or 1 */\r
+/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */\r
+\r
+\r
+#define _USE_FORWARD 0 /* 0 or 1 */\r
+/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */\r
+\r
+\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ Locale and Namespace Configurations\r
+/----------------------------------------------------------------------------*/\r
+\r
+#define _CODE_PAGE 1250\r
+/* The _CODE_PAGE specifies the OEM code page to be used on the target system.\r
+/ Incorrect setting of the code page can cause a file open failure.\r
+/\r
+/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)\r
+/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)\r
+/ 949 - Korean (DBCS, OEM, Windows)\r
+/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)\r
+/ 1250 - Central Europe (Windows)\r
+/ 1251 - Cyrillic (Windows)\r
+/ 1252 - Latin 1 (Windows)\r
+/ 1253 - Greek (Windows)\r
+/ 1254 - Turkish (Windows)\r
+/ 1255 - Hebrew (Windows)\r
+/ 1256 - Arabic (Windows)\r
+/ 1257 - Baltic (Windows)\r
+/ 1258 - Vietnam (OEM, Windows)\r
+/ 437 - U.S. (OEM)\r
+/ 720 - Arabic (OEM)\r
+/ 737 - Greek (OEM)\r
+/ 775 - Baltic (OEM)\r
+/ 850 - Multilingual Latin 1 (OEM)\r
+/ 858 - Multilingual Latin 1 + Euro (OEM)\r
+/ 852 - Latin 2 (OEM)\r
+/ 855 - Cyrillic (OEM)\r
+/ 866 - Russian (OEM)\r
+/ 857 - Turkish (OEM)\r
+/ 862 - Hebrew (OEM)\r
+/ 874 - Thai (OEM, Windows)\r
+/ 1 - ASCII only (Valid for non LFN cfg.)\r
+*/\r
+\r
+\r
+#define _USE_LFN 0 /* 0, 1 or 2 */\r
+#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */\r
+/* The _USE_LFN option switches the LFN support.\r
+/\r
+/ 0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect.\r
+/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT.\r
+/ 2: Enable LFN with dynamic working buffer on the STACK.\r
+/\r
+/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN,\r
+/ two Unicode handling functions ff_convert() and ff_wtoupper() must be added\r
+/ to the project. */\r
+\r
+\r
+#define _LFN_UNICODE 0 /* 0 or 1 */\r
+/* To switch the character code set on FatFs API to Unicode,\r
+/ enable LFN feature and set _LFN_UNICODE to 1.\r
+*/\r
+\r
+\r
+#define _FS_RPATH 0 /* 0 or 1 */\r
+/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir,\r
+/ f_chdrive function are available.\r
+/ Note that output of the f_readdir fnction is affected by this option. */\r
+\r
+\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ Physical Drive Configurations\r
+/----------------------------------------------------------------------------*/\r
+\r
+#define _DRIVES 1\r
+/* Number of volumes (logical drives) to be used. */\r
+\r
+\r
+#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */\r
+/* Maximum sector size to be handled.\r
+/ Always set 512 for memory card and hard disk but a larger value may be\r
+/ required for floppy disk (512/1024) and optical disk (512/2048).\r
+/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted\r
+/ to the disk_ioctl function. */\r
+\r
+\r
+#define _MULTI_PARTITION 0 /* 0 or 1 */\r
+/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical\r
+/ drive number and can mount only first primaly partition. When it is set to 1,\r
+/ each volume is tied to the partitions listed in Drives[]. */\r
+\r
+\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ System Configurations\r
+/----------------------------------------------------------------------------*/\r
+\r
+#define _WORD_ACCESS 0 /* 0 or 1 */\r
+/* The _WORD_ACCESS option defines which access method is used to the word\r
+/ data on the FAT volume.\r
+/\r
+/ 0: Byte-by-byte access. Always compatible with all platforms.\r
+/ 1: Word access. Do not choose this unless following condition is met.\r
+/\r
+/ When the byte order on the memory is big-endian or address miss-aligned\r
+/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.\r
+/ If it is not the case, the value can also be set to 1 to improve the\r
+/ performance and code size. */\r
+\r
+\r
+#define _FS_REENTRANT 1 /* 0 or 1 */\r
+#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */\r
+#define _SYNC_t void * /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */\r
+/* The _FS_REENTRANT option switches the reentrancy of the FatFs module.\r
+/\r
+/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.\r
+/ 1: Enable reentrancy. Also user provided synchronization handlers,\r
+/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj\r
+/ function must be added to the project. */\r
+\r
+\r
+#endif /* _FFCONFIG */\r
--- /dev/null
+/*\r
+ FreeRTOS V6.0.2 - Copyright (C) 2010 Real Time Engineers Ltd.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * If you are: *\r
+ * *\r
+ * + New to FreeRTOS, *\r
+ * + Wanting to learn FreeRTOS or multitasking in general quickly *\r
+ * + Looking for basic training, *\r
+ * + Wanting to improve your FreeRTOS skills and productivity *\r
+ * *\r
+ * then take a look at the FreeRTOS eBook *\r
+ * *\r
+ * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ * A pdf reference manual is also available. Both are usually delivered *\r
+ * to your inbox within 20 minutes to two hours when purchased between 8am *\r
+ * and 8pm GMT (although please allow up to 24 hours in case of *\r
+ * exceptional circumstances). Thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ ***NOTE*** The exception to the GPL is included to allow you to distribute\r
+ a combined work that includes FreeRTOS without being obliged to provide the\r
+ source code for proprietary components outside of the FreeRTOS kernel.\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public \r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it \r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained \r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+#ifndef FREERTOS_CONFIG_H\r
+#define FREERTOS_CONFIG_H\r
+\r
+#include "LPC17xx.h"\r
+\r
+/*-----------------------------------------------------------\r
+ * Application specific definitions.\r
+ *\r
+ * These definitions should be adjusted for your particular hardware and\r
+ * application requirements.\r
+ *\r
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE\r
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.\r
+ *----------------------------------------------------------*/\r
+\r
+#define configUSE_PREEMPTION 1\r
+#define configUSE_IDLE_HOOK 0\r
+#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )\r
+#define configUSE_TICK_HOOK 1\r
+#define configCPU_CLOCK_HZ ( ( unsigned long ) 99000000 )\r
+#define configTICK_RATE_HZ ( ( portTickType ) 1000 )\r
+#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 80 )\r
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 19 * 1024 ) )\r
+#define configMAX_TASK_NAME_LEN ( 12 )\r
+#define configUSE_TRACE_FACILITY 1\r
+#define configUSE_16_BIT_TICKS 0\r
+#define configIDLE_SHOULD_YIELD 0\r
+#define configUSE_CO_ROUTINES 0\r
+#define configUSE_MUTEXES 1\r
+\r
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )\r
+\r
+#define configUSE_COUNTING_SEMAPHORES 0\r
+#define configUSE_ALTERNATIVE_API 0\r
+#define configCHECK_FOR_STACK_OVERFLOW 2\r
+#define configUSE_RECURSIVE_MUTEXES 1\r
+#define configQUEUE_REGISTRY_SIZE 10\r
+#define configGENERATE_RUN_TIME_STATS 1\r
+\r
+/* Set the following definitions to 1 to include the API function, or zero\r
+to exclude the API function. */\r
+\r
+#define INCLUDE_vTaskPrioritySet 1\r
+#define INCLUDE_uxTaskPriorityGet 1\r
+#define INCLUDE_vTaskDelete 1\r
+#define INCLUDE_vTaskCleanUpResources 0\r
+#define INCLUDE_vTaskSuspend 1\r
+#define INCLUDE_vTaskDelayUntil 1\r
+#define INCLUDE_vTaskDelay 1\r
+#define INCLUDE_uxTaskGetStackHighWaterMark 1\r
+\r
+/*-----------------------------------------------------------\r
+ * Ethernet configuration.\r
+ *-----------------------------------------------------------*/\r
+\r
+/* MAC address configuration. */\r
+#define configMAC_ADDR0 0x00\r
+#define configMAC_ADDR1 0x12\r
+#define configMAC_ADDR2 0x13\r
+#define configMAC_ADDR3 0x10\r
+#define configMAC_ADDR4 0x15\r
+#define configMAC_ADDR5 0x11\r
+\r
+/* IP address configuration. */\r
+#define configIP_ADDR0 192\r
+#define configIP_ADDR1 168\r
+#define configIP_ADDR2 0\r
+#define configIP_ADDR3 201\r
+\r
+/* Netmask configuration. */\r
+#define configNET_MASK0 255\r
+#define configNET_MASK1 255\r
+#define configNET_MASK2 255\r
+#define configNET_MASK3 0\r
+\r
+/* Use the system definition, if there is one */\r
+#ifdef __NVIC_PRIO_BITS\r
+ #define configPRIO_BITS __NVIC_PRIO_BITS\r
+#else\r
+ #define configPRIO_BITS 5 /* 32 priority levels */\r
+#endif\r
+\r
+/* The lowest priority. */\r
+#define configKERNEL_INTERRUPT_PRIORITY ( 31 << (8 - configPRIO_BITS) )\r
+/* Priority 5, or 160 as only the top three bits are implemented. */\r
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << (8 - configPRIO_BITS) )\r
+\r
+/* Priorities passed to NVIC_SetPriority() do not require shifting as the\r
+function does the shifting itself. Note these priorities need to be equal to\r
+or lower than configMAX_SYSCALL_INTERRUPT_PRIORITY - therefore the numeric\r
+value needs to be equal to or greater than 5 (on the Cortex M3 the lower the\r
+numeric value the higher the interrupt priority). */\r
+#define configEMAC_INTERRUPT_PRIORITY 5\r
+#define configUSB_INTERRUPT_PRIORITY 6\r
+\r
+\r
+\r
+/*-----------------------------------------------------------\r
+ * Macros required to setup the timer for the run time stats.\r
+ *-----------------------------------------------------------*/\r
+extern void vConfigureTimerForRunTimeStats( void );\r
+#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()\r
+#define portGET_RUN_TIME_COUNTER_VALUE() TIM0->TC\r
+\r
+\r
+/* The structure that is passed on the xLCDQueue. Put here for convenience. */\r
+typedef struct\r
+{\r
+ char *pcMessage;\r
+} xLCDMessage;\r
+\r
+#endif /* FREERTOS_CONFIG_H */\r
--- /dev/null
+/*\r
+ FreeRTOS V6.0.2 - Copyright (C) 2010 Real Time Engineers Ltd.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * If you are: *\r
+ * *\r
+ * + New to FreeRTOS, *\r
+ * + Wanting to learn FreeRTOS or multitasking in general quickly *\r
+ * + Looking for basic training, *\r
+ * + Wanting to improve your FreeRTOS skills and productivity *\r
+ * *\r
+ * then take a look at the FreeRTOS eBook *\r
+ * *\r
+ * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ * A pdf reference manual is also available. Both are usually delivered *\r
+ * to your inbox within 20 minutes to two hours when purchased between 8am *\r
+ * and 8pm GMT (although please allow up to 24 hours in case of *\r
+ * exceptional circumstances). Thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ ***NOTE*** The exception to the GPL is included to allow you to distribute\r
+ a combined work that includes FreeRTOS without being obliged to provide the\r
+ source code for proprietary components outside of the FreeRTOS kernel.\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public \r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it \r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained \r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+#ifndef LED_HH\r
+#define LED_HH\r
+\r
+void vToggleLED( unsigned long ulLED );\r
+void vSetLEDState( unsigned long ulLED, long lState );\r
+long lGetLEDState( unsigned long ulLED );\r
+\r
+#endif\r
--- /dev/null
+/*****************************************************************************
+ * Copyright (c) 2009 Rowley Associates Limited. *
+ * *
+ * This file may be distributed under the terms of the License Agreement *
+ * provided with this software. *
+ * *
+ * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE *
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preprocessor Definitions
+ * ------------------------
+ *
+ * STARTUP_FROM_RESET
+ *
+ * If defined, the program will startup from power-on/reset. If not defined
+ * the program will just loop endlessly from power-on/reset.
+ *
+ * This definition is not defined by default on this target because the
+ * debugger is unable to reset this target and maintain control of it over the
+ * JTAG interface. The advantage of doing this is that it allows the debugger
+ * to reset the CPU and run programs from a known reset CPU state on each run.
+ * It also acts as a safety net if you accidently download a program in FLASH
+ * that crashes and prevents the debugger from taking control over JTAG
+ * rendering the target unusable over JTAG. The obvious disadvantage of doing
+ * this is that your application will not startup without the debugger.
+ *
+ * We advise that on this target you keep STARTUP_FROM_RESET undefined whilst
+ * you are developing and only define STARTUP_FROM_RESET when development is
+ * complete.A
+ *
+ *
+ * CONFIGURE_USB
+ *
+ * If defined, the USB clock will be configured.
+ *
+ *****************************************************************************/
+
+#include <LPC1000.h>
+
+#if OSCILLATOR_CLOCK_FREQUENCY==12000000
+
+#ifdef FULL_SPEED
+
+/* Fosc = 12Mhz, Fcco = 400Mhz, cclk = 100Mhz */
+#ifndef PLL0CFG_VAL
+#define PLL0CFG_VAL ((49 << PLL0CFG_MSEL0_BIT) | (2 << PLL0CFG_NSEL0_BIT))
+#endif
+
+#ifndef CCLKCFG_VAL
+#define CCLKCFG_VAL 3
+#endif
+
+#ifndef FLASHCFG_VAL
+#define FLASHCFG_VAL 0x0000403A
+#endif
+
+#else
+
+/* Fosc = 12Mhz, Fcco = 288Mhz, cclk = 72Mhz */
+#ifndef PLL0CFG_VAL
+#define PLL0CFG_VAL ((11 << PLL0CFG_MSEL0_BIT) | (0 << PLL0CFG_NSEL0_BIT))
+#endif
+
+#ifndef CCLKCFG_VAL
+#define CCLKCFG_VAL 3
+#endif
+
+#ifndef FLASHCFG_VAL
+#define FLASHCFG_VAL 0x0000303A
+#endif
+
+#endif
+
+/* Fosc = 12Mhz, Fcco = 192Mhz, usbclk = 48Mhz */
+#ifndef PLL1CFG_VAL
+#define PLL1CFG_VAL ((3 << PLL1CFG_MSEL1_BIT) | (1 << PLL1CFG_PSEL1_BIT))
+#endif
+
+#endif
+
+ .global reset_handler
+
+ .syntax unified
+
+ .section .vectors, "ax"
+ .code 16
+ .align 0
+ .global _vectors
+
+.macro DEFAULT_ISR_HANDLER name=
+ .thumb_func
+ .weak \name
+\name:
+1: b 1b /* endless loop */
+.endm
+
+.extern xPortPendSVHandler
+.extern xPortSysTickHandler
+.extern vPortSVCHandler
+.extern vEMAC_ISR;
+
+_vectors:
+ .word __stack_end__
+#ifdef STARTUP_FROM_RESET
+ .word reset_handler
+#else
+ .word reset_wait
+#endif /* STARTUP_FROM_RESET */
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0 // Reserved
+ .word 0 // Reserved
+ .word 0 // Reserved
+ .word 0 // Reserved
+ .word vPortSVCHandler
+ .word DebugMon_Handler
+ .word 0 // Reserved
+ .word xPortPendSVHandler
+ .word xPortSysTickHandler
+ .word WDT_IRQHandler
+ .word TIMER0_IRQHandler
+ .word TIMER1_IRQHandler
+ .word TIMER2_IRQHandler
+ .word TIMER3_IRQHandler
+ .word UART0_IRQHandler
+ .word UART1_IRQHandler
+ .word UART2_IRQHandler
+ .word UART3_IRQHandler
+ .word PWM1_IRQHandler
+ .word I2C0_IRQHandler
+ .word I2C1_IRQHandler
+ .word I2C2_IRQHandler
+ .word SPI_IRQHandler
+ .word SSP0_IRQHandler
+ .word SSP1_IRQHandler
+ .word PLL0_IRQHandler
+ .word RTC_IRQHandler
+ .word EINT0_IRQHandler
+ .word EINT1_IRQHandler
+ .word EINT2_IRQHandler
+ .word EINT3_IRQHandler
+ .word ADC_IRQHandler
+ .word BOD_IRQHandler
+ .word USB_IRQHandler
+ .word CAN_IRQHandler
+ .word GPDMA_IRQHandler
+ .word I2S_IRQHandler
+ .word vEMAC_ISR
+ .word RIT_IRQHandler
+ .word MCPWM_IRQHandler
+ .word QEI_IRQHandler
+ .word PLL1_IRQHandler
+ .word USBACT_IRQHandler
+ .word CANACT_IRQHandler
+
+ .section .init, "ax"
+ .thumb_func
+
+ reset_handler:
+#ifndef __FLASH_BUILD
+ /* If this is a RAM build, configure vector table offset register to point
+ to the RAM vector table. */
+ ldr r0, =0xE000ED08
+ ldr r1, =_vectors
+ str r1, [r0]
+#endif
+
+ ldr r0, =SC_BASE_ADDRESS
+
+ /* Configure PLL0 Multiplier/Divider */
+ ldr r1, [r0, #PLL0STAT_OFFSET]
+ tst r1, #PLL0STAT_PLLC0_STAT
+ beq 1f
+
+ /* Disconnect PLL0 */
+ ldr r1, =PLL0CON_PLLE0
+ str r1, [r0, #PLL0CON_OFFSET]
+ mov r1, #0xAA
+ str r1, [r0, #PLL0FEED_OFFSET]
+ mov r1, #0x55
+ str r1, [r0, #PLL0FEED_OFFSET]
+1:
+ /* Disable PLL0 */
+ ldr r1, =0
+ str r1, [r0, #PLL0CON_OFFSET]
+ mov r1, #0xAA
+ str r1, [r0, #PLL0FEED_OFFSET]
+ mov r1, #0x55
+ str r1, [r0, #PLL0FEED_OFFSET]
+
+ /* Enable main oscillator */
+ ldr r1, [r0, #SCS_OFFSET]
+ orr r1, r1, #SCS_OSCEN
+ str r1, [r0, #SCS_OFFSET]
+1:
+ ldr r1, [r0, #SCS_OFFSET]
+ tst r1, #SCS_OSCSTAT
+ beq 1b
+
+ /* Select main oscillator as the PLL0 clock source */
+ ldr r1, =1
+ str r1, [r0, #CLKSRCSEL_OFFSET]
+
+ /* Set PLL0CFG */
+ ldr r1, =PLL0CFG_VAL
+ str r1, [r0, #PLL0CFG_OFFSET]
+ mov r1, #0xAA
+ str r1, [r0, #PLL0FEED_OFFSET]
+ mov r1, #0x55
+ str r1, [r0, #PLL0FEED_OFFSET]
+
+ /* Enable PLL0 */
+ ldr r1, =PLL0CON_PLLE0
+ str r1, [r0, #PLL0CON_OFFSET]
+ mov r1, #0xAA
+ str r1, [r0, #PLL0FEED_OFFSET]
+ mov r1, #0x55
+ str r1, [r0, #PLL0FEED_OFFSET]
+
+#ifdef CCLKCFG_VAL
+ /* Set the CPU clock divider */
+ ldr r1, =CCLKCFG_VAL
+ str r1, [r0, #CCLKCFG_OFFSET]
+#endif
+
+#ifdef FLASHCFG_VAL
+ /* Configure the FLASH accelerator */
+ ldr r1, =FLASHCFG_VAL
+ str r1, [r0, #FLASHCFG_OFFSET]
+#endif
+
+ /* Wait for PLL0 to lock */
+1:
+ ldr r1, [r0, #PLL0STAT_OFFSET]
+ tst r1, #PLL0STAT_PLOCK0
+ beq 1b
+
+ /* PLL0 Locked, connect PLL as clock source */
+ mov r1, #(PLL0CON_PLLE0 | PLL0CON_PLLC0)
+ str r1, [r0, #PLL0CON_OFFSET]
+ mov r1, #0xAA
+ str r1, [r0, #PLL0FEED_OFFSET]
+ mov r1, #0x55
+ str r1, [r0, #PLL0FEED_OFFSET]
+ /* Wait for PLL0 to connect */
+1:
+ ldr r1, [r0, #PLL0STAT_OFFSET]
+ tst r1, #PLL0STAT_PLLC0_STAT
+ beq 1b
+
+#ifdef CONFIGURE_USB
+ /* Configure PLL1 Multiplier/Divider */
+ ldr r1, [r0, #PLL1STAT_OFFSET]
+ tst r1, #PLL1STAT_PLLC1_STAT
+ beq 1f
+
+ /* Disconnect PLL1 */
+ ldr r1, =PLL1CON_PLLE1
+ str r1, [r0, #PLL1CON_OFFSET]
+ mov r1, #0xAA
+ str r1, [r0, #PLL1FEED_OFFSET]
+ mov r1, #0x55
+ str r1, [r0, #PLL1FEED_OFFSET]
+1:
+ /* Disable PLL1 */
+ ldr r1, =0
+ str r1, [r0, #PLL1CON_OFFSET]
+ mov r1, #0xAA
+ str r1, [r0, #PLL1FEED_OFFSET]
+ mov r1, #0x55
+ str r1, [r0, #PLL1FEED_OFFSET]
+
+ /* Set PLL1CFG */
+ ldr r1, =PLL1CFG_VAL
+ str r1, [r0, #PLL1CFG_OFFSET]
+ mov r1, #0xAA
+ str r1, [r0, #PLL1FEED_OFFSET]
+ mov r1, #0x55
+ str r1, [r0, #PLL1FEED_OFFSET]
+
+ /* Enable PLL1 */
+ ldr r1, =PLL1CON_PLLE1
+ str r1, [r0, #PLL1CON_OFFSET]
+ mov r1, #0xAA
+ str r1, [r0, #PLL1FEED_OFFSET]
+ mov r1, #0x55
+ str r1, [r0, #PLL1FEED_OFFSET]
+
+ /* Wait for PLL1 to lock */
+1:
+ ldr r1, [r0, #PLL1STAT_OFFSET]
+ tst r1, #PLL1STAT_PLOCK1
+ beq 1b
+
+ /* PLL1 Locked, connect PLL as clock source */
+ mov r1, #(PLL1CON_PLLE1 | PLL1CON_PLLC1)
+ str r1, [r0, #PLL1CON_OFFSET]
+ mov r1, #0xAA
+ str r1, [r0, #PLL1FEED_OFFSET]
+ mov r1, #0x55
+ str r1, [r0, #PLL1FEED_OFFSET]
+ /* Wait for PLL1 to connect */
+1:
+ ldr r1, [r0, #PLL1STAT_OFFSET]
+ tst r1, #PLL1STAT_PLLC1_STAT
+ beq 1b
+#endif
+
+ b _start
+
+DEFAULT_ISR_HANDLER NMI_Handler
+DEFAULT_ISR_HANDLER HardFault_Handler
+DEFAULT_ISR_HANDLER MemManage_Handler
+DEFAULT_ISR_HANDLER BusFault_Handler
+DEFAULT_ISR_HANDLER UsageFault_Handler
+DEFAULT_ISR_HANDLER SVC_Handler
+DEFAULT_ISR_HANDLER DebugMon_Handler
+DEFAULT_ISR_HANDLER PendSV_Handler
+DEFAULT_ISR_HANDLER SysTick_Handler
+DEFAULT_ISR_HANDLER WDT_IRQHandler
+DEFAULT_ISR_HANDLER TIMER0_IRQHandler
+DEFAULT_ISR_HANDLER TIMER1_IRQHandler
+DEFAULT_ISR_HANDLER TIMER2_IRQHandler
+DEFAULT_ISR_HANDLER TIMER3_IRQHandler
+DEFAULT_ISR_HANDLER UART0_IRQHandler
+DEFAULT_ISR_HANDLER UART1_IRQHandler
+DEFAULT_ISR_HANDLER UART2_IRQHandler
+DEFAULT_ISR_HANDLER UART3_IRQHandler
+DEFAULT_ISR_HANDLER PWM1_IRQHandler
+DEFAULT_ISR_HANDLER I2C0_IRQHandler
+DEFAULT_ISR_HANDLER I2C1_IRQHandler
+DEFAULT_ISR_HANDLER I2C2_IRQHandler
+DEFAULT_ISR_HANDLER SPI_IRQHandler
+DEFAULT_ISR_HANDLER SSP0_IRQHandler
+DEFAULT_ISR_HANDLER SSP1_IRQHandler
+DEFAULT_ISR_HANDLER PLL0_IRQHandler
+DEFAULT_ISR_HANDLER RTC_IRQHandler
+DEFAULT_ISR_HANDLER EINT0_IRQHandler
+DEFAULT_ISR_HANDLER EINT1_IRQHandler
+DEFAULT_ISR_HANDLER EINT2_IRQHandler
+DEFAULT_ISR_HANDLER EINT3_IRQHandler
+DEFAULT_ISR_HANDLER ADC_IRQHandler
+DEFAULT_ISR_HANDLER BOD_IRQHandler
+DEFAULT_ISR_HANDLER USB_IRQHandler
+DEFAULT_ISR_HANDLER CAN_IRQHandler
+DEFAULT_ISR_HANDLER GPDMA_IRQHandler
+DEFAULT_ISR_HANDLER I2S_IRQHandler
+DEFAULT_ISR_HANDLER ENET_IRQHandler
+DEFAULT_ISR_HANDLER RIT_IRQHandler
+DEFAULT_ISR_HANDLER MCPWM_IRQHandler
+DEFAULT_ISR_HANDLER QEI_IRQHandler
+DEFAULT_ISR_HANDLER PLL1_IRQHandler
+DEFAULT_ISR_HANDLER USBACT_IRQHandler
+DEFAULT_ISR_HANDLER CANACT_IRQHandler
+
+#ifndef STARTUP_FROM_RESET
+DEFAULT_ISR_HANDLER reset_wait
+#endif /* STARTUP_FROM_RESET */
+
--- /dev/null
+#ifndef __LPC17xx_H\r
+#define __LPC17xx_H\r
+\r
+/* System Control Block (SCB) includes:\r
+ Flash Accelerator Module, Clocking and Power Control, External Interrupts,\r
+ Reset, System Control and Status\r
+*/\r
+#define SCB_BASE_ADDR 0x400FC000\r
+\r
+#define PCONP_PCTIM0 0x00000002\r
+#define PCONP_PCTIM1 0x00000004\r
+#define PCONP_PCUART0 0x00000008\r
+#define PCONP_PCUART1 0x00000010\r
+#define PCONP_PCPWM1 0x00000040\r
+#define PCONP_PCI2C0 0x00000080\r
+#define PCONP_PCSPI 0x00000100\r
+#define PCONP_PCRTC 0x00000200\r
+#define PCONP_PCSSP1 0x00000400\r
+#define PCONP_PCAD 0x00001000\r
+#define PCONP_PCCAN1 0x00002000\r
+#define PCONP_PCCAN2 0x00004000\r
+#define PCONP_PCGPIO 0x00008000\r
+#define PCONP_PCRIT 0x00010000\r
+#define PCONP_PCMCPWM 0x00020000\r
+#define PCONP_PCQEI 0x00040000\r
+#define PCONP_PCI2C1 0x00080000\r
+#define PCONP_PCSSP0 0x00200000\r
+#define PCONP_PCTIM2 0x00400000\r
+#define PCONP_PCTIM3 0x00800000\r
+#define PCONP_PCUART2 0x01000000\r
+#define PCONP_PCUART3 0x02000000\r
+#define PCONP_PCI2C2 0x04000000\r
+#define PCONP_PCI2S 0x08000000\r
+#define PCONP_PCGPDMA 0x20000000\r
+#define PCONP_PCENET 0x40000000\r
+#define PCONP_PCUSB 0x80000000\r
+\r
+#define PLLCON_PLLE 0x00000001\r
+#define PLLCON_PLLC 0x00000002\r
+#define PLLCON_MASK 0x00000003\r
+\r
+#define PLLCFG_MUL1 0x00000000\r
+#define PLLCFG_MUL2 0x00000001\r
+#define PLLCFG_MUL3 0x00000002\r
+#define PLLCFG_MUL4 0x00000003\r
+#define PLLCFG_MUL5 0x00000004\r
+#define PLLCFG_MUL6 0x00000005\r
+#define PLLCFG_MUL7 0x00000006\r
+#define PLLCFG_MUL8 0x00000007\r
+#define PLLCFG_MUL9 0x00000008\r
+#define PLLCFG_MUL10 0x00000009\r
+#define PLLCFG_MUL11 0x0000000A\r
+#define PLLCFG_MUL12 0x0000000B\r
+#define PLLCFG_MUL13 0x0000000C\r
+#define PLLCFG_MUL14 0x0000000D\r
+#define PLLCFG_MUL15 0x0000000E\r
+#define PLLCFG_MUL16 0x0000000F\r
+#define PLLCFG_MUL17 0x00000010\r
+#define PLLCFG_MUL18 0x00000011\r
+#define PLLCFG_MUL19 0x00000012\r
+#define PLLCFG_MUL20 0x00000013\r
+#define PLLCFG_MUL21 0x00000014\r
+#define PLLCFG_MUL22 0x00000015\r
+#define PLLCFG_MUL23 0x00000016\r
+#define PLLCFG_MUL24 0x00000017\r
+#define PLLCFG_MUL25 0x00000018\r
+#define PLLCFG_MUL26 0x00000019\r
+#define PLLCFG_MUL27 0x0000001A\r
+#define PLLCFG_MUL28 0x0000001B\r
+#define PLLCFG_MUL29 0x0000001C\r
+#define PLLCFG_MUL30 0x0000001D\r
+#define PLLCFG_MUL31 0x0000001E\r
+#define PLLCFG_MUL32 0x0000001F\r
+#define PLLCFG_MUL33 0x00000020\r
+#define PLLCFG_MUL34 0x00000021\r
+#define PLLCFG_MUL35 0x00000022\r
+#define PLLCFG_MUL36 0x00000023\r
+\r
+#define PLLCFG_DIV1 0x00000000\r
+#define PLLCFG_DIV2 0x00010000\r
+#define PLLCFG_DIV3 0x00020000\r
+#define PLLCFG_DIV4 0x00030000\r
+#define PLLCFG_DIV5 0x00040000\r
+#define PLLCFG_DIV6 0x00050000\r
+#define PLLCFG_DIV7 0x00060000\r
+#define PLLCFG_DIV8 0x00070000\r
+#define PLLCFG_DIV9 0x00080000\r
+#define PLLCFG_DIV10 0x00090000\r
+#define PLLCFG_MASK 0x00FF7FFF\r
+\r
+#define PLLSTAT_MSEL_MASK 0x00007FFF\r
+#define PLLSTAT_NSEL_MASK 0x00FF0000\r
+\r
+#define PLLSTAT_PLLE (1 << 24)\r
+#define PLLSTAT_PLLC (1 << 25)\r
+#define PLLSTAT_PLOCK (1 << 26)\r
+\r
+#define PLLFEED_FEED1 0x000000AA\r
+#define PLLFEED_FEED2 0x00000055\r
+\r
+#define NVIC_IRQ_WDT 0u // IRQ0, exception number 16\r
+#define NVIC_IRQ_TIMER0 1u // IRQ1, exception number 17\r
+#define NVIC_IRQ_TIMER1 2u // IRQ2, exception number 18\r
+#define NVIC_IRQ_TIMER2 3u // IRQ3, exception number 19\r
+#define NVIC_IRQ_TIMER3 4u // IRQ4, exception number 20\r
+#define NVIC_IRQ_UART0 5u // IRQ5, exception number 21\r
+#define NVIC_IRQ_UART1 6u // IRQ6, exception number 22\r
+#define NVIC_IRQ_UART2 7u // IRQ7, exception number 23\r
+#define NVIC_IRQ_UART3 8u // IRQ8, exception number 24\r
+#define NVIC_IRQ_PWM1 9u // IRQ9, exception number 25\r
+#define NVIC_IRQ_I2C0 10u // IRQ10, exception number 26\r
+#define NVIC_IRQ_I2C1 11u // IRQ11, exception number 27\r
+#define NVIC_IRQ_I2C2 12u // IRQ12, exception number 28\r
+#define NVIC_IRQ_SPI 13u // IRQ13, exception number 29\r
+#define NVIC_IRQ_SSP0 14u // IRQ14, exception number 30\r
+#define NVIC_IRQ_SSP1 15u // IRQ15, exception number 31\r
+#define NVIC_IRQ_PLL0 16u // IRQ16, exception number 32\r
+#define NVIC_IRQ_RTC 17u // IRQ17, exception number 33\r
+#define NVIC_IRQ_EINT0 18u // IRQ18, exception number 34\r
+#define NVIC_IRQ_EINT1 19u // IRQ19, exception number 35\r
+#define NVIC_IRQ_EINT2 20u // IRQ20, exception number 36\r
+#define NVIC_IRQ_EINT3 21u // IRQ21, exception number 37\r
+#define NVIC_IRQ_ADC 22u // IRQ22, exception number 38\r
+#define NVIC_IRQ_BOD 23u // IRQ23, exception number 39\r
+#define NVIC_IRQ_USB 24u // IRQ24, exception number 40\r
+#define NVIC_IRQ_CAN 25u // IRQ25, exception number 41\r
+#define NVIC_IRQ_GPDMA 26u // IRQ26, exception number 42\r
+#define NVIC_IRQ_I2S 27u // IRQ27, exception number 43\r
+#define NVIC_IRQ_ETHERNET 28u // IRQ28, exception number 44\r
+#define NVIC_IRQ_RIT 29u // IRQ29, exception number 45\r
+#define NVIC_IRQ_MCPWM 30u // IRQ30, exception number 46\r
+#define NVIC_IRQ_QE 31u // IRQ31, exception number 47\r
+#define NVIC_IRQ_PLL1 32u // IRQ32, exception number 48\r
+#define NVIC_IRQ_USB_ACT 33u // IRQ33, exception number 49\r
+#define NVIC_IRQ_CAN_ACT 34u // IRQ34, exception number 50\r
+\r
+\r
+#endif // __LPC17xx_H\r
+\r
+\r
+#ifndef CMSIS_17xx_H\r
+#define CMSIS_17xx_H\r
+\r
+/******************************************************************************\r
+ * @file: LPC17xx.h\r
+ * @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Header File for\r
+ * NXP LPC17xx Device Series\r
+ * @version: V1.1\r
+ * @date: 14th May 2009\r
+ *----------------------------------------------------------------------------\r
+ *\r
+ * Copyright (C) 2008 ARM Limited. All rights reserved.\r
+ *\r
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M3\r
+ * processor based microcontrollers. This file can be freely distributed\r
+ * within development tools that are supporting such ARM based processors.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
+ *\r
+ ******************************************************************************/\r
+\r
+\r
+#ifndef __LPC17xx_H__\r
+#define __LPC17xx_H__\r
+\r
+/*\r
+ * ==========================================================================\r
+ * ---------- Interrupt Number Definition -----------------------------------\r
+ * ==========================================================================\r
+ */\r
+\r
+typedef enum IRQn\r
+{\r
+/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/\r
+ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */\r
+ MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */\r
+ BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */\r
+ UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */\r
+ SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */\r
+ DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */\r
+ PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */\r
+ SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */\r
+\r
+/****** LPC17xx Specific Interrupt Numbers *******************************************************/\r
+ WDT_IRQn = 0, /*!< Watchdog Timer Interrupt */\r
+ TIMER0_IRQn = 1, /*!< Timer0 Interrupt */\r
+ TIMER1_IRQn = 2, /*!< Timer1 Interrupt */\r
+ TIMER2_IRQn = 3, /*!< Timer2 Interrupt */\r
+ TIMER3_IRQn = 4, /*!< Timer3 Interrupt */\r
+ UART0_IRQn = 5, /*!< UART0 Interrupt */\r
+ UART1_IRQn = 6, /*!< UART1 Interrupt */\r
+ UART2_IRQn = 7, /*!< UART2 Interrupt */\r
+ UART3_IRQn = 8, /*!< UART3 Interrupt */\r
+ PWM1_IRQn = 9, /*!< PWM1 Interrupt */\r
+ I2C0_IRQn = 10, /*!< I2C0 Interrupt */\r
+ I2C1_IRQn = 11, /*!< I2C1 Interrupt */\r
+ I2C2_IRQn = 12, /*!< I2C2 Interrupt */\r
+ SPI_IRQn = 13, /*!< SPI Interrupt */\r
+ SSP0_IRQn = 14, /*!< SSP0 Interrupt */\r
+ SSP1_IRQn = 15, /*!< SSP1 Interrupt */\r
+ PLL0_IRQn = 16, /*!< PLL0 Lock (Main PLL) Interrupt */\r
+ RTC_IRQn = 17, /*!< Real Time Clock Interrupt */\r
+ EINT0_IRQn = 18, /*!< External Interrupt 0 Interrupt */\r
+ EINT1_IRQn = 19, /*!< External Interrupt 1 Interrupt */\r
+ EINT2_IRQn = 20, /*!< External Interrupt 2 Interrupt */\r
+ EINT3_IRQn = 21, /*!< External Interrupt 3 Interrupt */\r
+ ADC_IRQn = 22, /*!< A/D Converter Interrupt */\r
+ BOD_IRQn = 23, /*!< Brown-Out Detect Interrupt */\r
+ USB_IRQn = 24, /*!< USB Interrupt */\r
+ CAN_IRQn = 25, /*!< CAN Interrupt */\r
+ DMA_IRQn = 26, /*!< General Purpose DMA Interrupt */\r
+ I2S_IRQn = 27, /*!< I2S Interrupt */\r
+ ENET_IRQn = 28, /*!< Ethernet Interrupt */\r
+ RIT_IRQn = 29, /*!< Repetitive Interrupt Timer Interrupt */\r
+ MCPWM_IRQn = 30, /*!< Motor Control PWM Interrupt */\r
+ QEI_IRQn = 31, /*!< Quadrature Encoder Interface Interrupt */\r
+ PLL1_IRQn = 32, /*!< PLL1 Lock (USB PLL) Interrupt */\r
+} IRQn_Type;\r
+\r
+\r
+/*\r
+ * ==========================================================================\r
+ * ----------- Processor and Core Peripheral Section ------------------------\r
+ * ==========================================================================\r
+ */\r
+\r
+/* Configuration of the Cortex-M3 Processor and Core Peripherals */\r
+#define __MPU_PRESENT 1 /*!< MPU present or not */\r
+#define __NVIC_PRIO_BITS 5 /*!< Number of Bits used for Priority Levels */\r
+#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */\r
+\r
+\r
+//#include "..\core_cm3.h" /* Cortex-M3 processor and core peripherals */\r
+#include "core_cm3.h"\r
+#include "system_LPC17xx.h" /* System Header */\r
+\r
+\r
+\r
+/**\r
+ * Initialize the system clock\r
+ *\r
+ * @param none\r
+ * @return none\r
+ *\r
+ * @brief Setup the microcontroller system.\r
+ * Initialize the System and update the SystemFrequency variable.\r
+ */\r
+extern void SystemInit (void);\r
+\r
+\r
+/******************************************************************************/\r
+/* Device Specific Peripheral registers structures */\r
+/******************************************************************************/\r
+\r
+/*------------- System Control (SC) ------------------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t FLASHCFG; /* Flash Accelerator Module */\r
+ uint32_t RESERVED0[31];\r
+ __IO uint32_t PLL0CON; /* Clocking and Power Control */\r
+ __IO uint32_t PLL0CFG;\r
+ __I uint32_t PLL0STAT;\r
+ __O uint32_t PLL0FEED;\r
+ uint32_t RESERVED1[4];\r
+ __IO uint32_t PLL1CON;\r
+ __IO uint32_t PLL1CFG;\r
+ __I uint32_t PLL1STAT;\r
+ __O uint32_t PLL1FEED;\r
+ uint32_t RESERVED2[4];\r
+ __IO uint32_t PCON;\r
+ __IO uint32_t PCONP;\r
+ uint32_t RESERVED3[15];\r
+ __IO uint32_t CCLKCFG;\r
+ __IO uint32_t USBCLKCFG;\r
+ __IO uint32_t CLKSRCSEL;\r
+ uint32_t RESERVED4[12];\r
+ __IO uint32_t EXTINT; /* External Interrupts */\r
+ uint32_t RESERVED5;\r
+ __IO uint32_t EXTMODE;\r
+ __IO uint32_t EXTPOLAR;\r
+ uint32_t RESERVED6[12];\r
+ __IO uint32_t RSID; /* Reset */\r
+ uint32_t RESERVED7[7];\r
+ __IO uint32_t SCS; /* Syscon Miscellaneous Registers */\r
+ __IO uint32_t IRCTRIM; /* Clock Dividers */\r
+ __IO uint32_t PCLKSEL0;\r
+ __IO uint32_t PCLKSEL1;\r
+ uint32_t RESERVED8[4];\r
+ __IO uint32_t USBIntSt; /* USB Device/OTG Interrupt Register */\r
+ uint32_t RESERVED9;\r
+ __IO uint32_t CLKOUTCFG; /* Clock Output Configuration */\r
+ } SC_TypeDef;\r
+\r
+/*------------- Pin Connect Block (PINCON) -----------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t PINSEL0;\r
+ __IO uint32_t PINSEL1;\r
+ __IO uint32_t PINSEL2;\r
+ __IO uint32_t PINSEL3;\r
+ __IO uint32_t PINSEL4;\r
+ __IO uint32_t PINSEL5;\r
+ __IO uint32_t PINSEL6;\r
+ __IO uint32_t PINSEL7;\r
+ __IO uint32_t PINSEL8;\r
+ __IO uint32_t PINSEL9;\r
+ __IO uint32_t PINSEL10;\r
+ uint32_t RESERVED0[5];\r
+ __IO uint32_t PINMODE0;\r
+ __IO uint32_t PINMODE1;\r
+ __IO uint32_t PINMODE2;\r
+ __IO uint32_t PINMODE3;\r
+ __IO uint32_t PINMODE4;\r
+ __IO uint32_t PINMODE5;\r
+ __IO uint32_t PINMODE6;\r
+ __IO uint32_t PINMODE7;\r
+ __IO uint32_t PINMODE8;\r
+ __IO uint32_t PINMODE9;\r
+ __IO uint32_t PINMODE_OD0;\r
+ __IO uint32_t PINMODE_OD1;\r
+ __IO uint32_t PINMODE_OD2;\r
+ __IO uint32_t PINMODE_OD3;\r
+ __IO uint32_t PINMODE_OD4;\r
+} PINCON_TypeDef;\r
+\r
+/*------------- General Purpose Input/Output (GPIO) --------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t FIODIR;\r
+ uint32_t RESERVED0[3];\r
+ __IO uint32_t FIOMASK;\r
+ __IO uint32_t FIOPIN;\r
+ __IO uint32_t FIOSET;\r
+ __O uint32_t FIOCLR;\r
+} GPIO_TypeDef;\r
+\r
+typedef struct\r
+{\r
+ __I uint32_t IntStatus;\r
+ __I uint32_t IO0IntStatR;\r
+ __I uint32_t IO0IntStatF;\r
+ __O uint32_t IO0IntClr;\r
+ __IO uint32_t IO0IntEnR;\r
+ __IO uint32_t IO0IntEnF;\r
+ uint32_t RESERVED0[3];\r
+ __I uint32_t IO2IntStatR;\r
+ __I uint32_t IO2IntStatF;\r
+ __O uint32_t IO2IntClr;\r
+ __IO uint32_t IO2IntEnR;\r
+ __IO uint32_t IO2IntEnF;\r
+} GPIOINT_TypeDef;\r
+\r
+/*------------- Timer (TIM) --------------------------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t IR;\r
+ __IO uint32_t TCR;\r
+ __IO uint32_t TC;\r
+ __IO uint32_t PR;\r
+ __IO uint32_t PC;\r
+ __IO uint32_t MCR;\r
+ __IO uint32_t MR0;\r
+ __IO uint32_t MR1;\r
+ __IO uint32_t MR2;\r
+ __IO uint32_t MR3;\r
+ __IO uint32_t CCR;\r
+ __I uint32_t CR0;\r
+ __I uint32_t CR1;\r
+ uint32_t RESERVED0[2];\r
+ __IO uint32_t EMR;\r
+ uint32_t RESERVED1[24];\r
+ __IO uint32_t CTCR;\r
+} TIM_TypeDef;\r
+\r
+/*------------- Pulse-Width Modulation (PWM) ---------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t IR;\r
+ __IO uint32_t TCR;\r
+ __IO uint32_t TC;\r
+ __IO uint32_t PR;\r
+ __IO uint32_t PC;\r
+ __IO uint32_t MCR;\r
+ __IO uint32_t MR0;\r
+ __IO uint32_t MR1;\r
+ __IO uint32_t MR2;\r
+ __IO uint32_t MR3;\r
+ __IO uint32_t CCR;\r
+ __I uint32_t CR0;\r
+ __I uint32_t CR1;\r
+ __I uint32_t CR2;\r
+ __I uint32_t CR3;\r
+ __IO uint32_t MR4;\r
+ __IO uint32_t MR5;\r
+ __IO uint32_t MR6;\r
+ __IO uint32_t PCR;\r
+ __IO uint32_t LER;\r
+ uint32_t RESERVED0[7];\r
+ __IO uint32_t CTCR;\r
+} PWM_TypeDef;\r
+\r
+/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/\r
+typedef struct\r
+{\r
+ union {\r
+ __I uint8_t RBR;\r
+ __O uint8_t THR;\r
+ __IO uint8_t DLL;\r
+ uint32_t RESERVED0;\r
+ };\r
+ union {\r
+ __IO uint8_t DLM;\r
+ __IO uint32_t IER;\r
+ };\r
+ union {\r
+ __I uint32_t IIR;\r
+ __O uint8_t FCR;\r
+ };\r
+ __IO uint8_t LCR;\r
+ uint8_t RESERVED1[7];\r
+ __IO uint8_t LSR;\r
+ uint8_t RESERVED2[7];\r
+ __IO uint8_t SCR;\r
+ uint8_t RESERVED3[3];\r
+ __IO uint32_t ACR;\r
+ __IO uint8_t ICR;\r
+ uint8_t RESERVED4[3];\r
+ __IO uint8_t FDR;\r
+ uint8_t RESERVED5[7];\r
+ __IO uint8_t TER;\r
+ uint8_t RESERVED6[27];\r
+ __IO uint8_t RS485CTRL;\r
+ uint8_t RESERVED7[3];\r
+ __IO uint8_t ADRMATCH;\r
+} UART_TypeDef;\r
+\r
+typedef struct\r
+{\r
+ union {\r
+ __I uint8_t RBR;\r
+ __O uint8_t THR;\r
+ __IO uint8_t DLL;\r
+ uint32_t RESERVED0;\r
+ };\r
+ union {\r
+ __IO uint8_t DLM;\r
+ __IO uint32_t IER;\r
+ };\r
+ union {\r
+ __I uint32_t IIR;\r
+ __O uint8_t FCR;\r
+ };\r
+ __IO uint8_t LCR;\r
+ uint8_t RESERVED1[3];\r
+ __IO uint8_t MCR;\r
+ uint8_t RESERVED2[3];\r
+ __IO uint8_t LSR;\r
+ uint8_t RESERVED3[3];\r
+ __IO uint8_t MSR;\r
+ uint8_t RESERVED4[3];\r
+ __IO uint8_t SCR;\r
+ uint8_t RESERVED5[3];\r
+ __IO uint32_t ACR;\r
+ uint32_t RESERVED6;\r
+ __IO uint32_t FDR;\r
+ uint32_t RESERVED7;\r
+ __IO uint8_t TER;\r
+ uint8_t RESERVED8[27];\r
+ __IO uint8_t RS485CTRL;\r
+ uint8_t RESERVED9[3];\r
+ __IO uint8_t ADRMATCH;\r
+ uint8_t RESERVED10[3];\r
+ __IO uint8_t RS485DLY;\r
+} UART1_TypeDef;\r
+\r
+/*------------- Serial Peripheral Interface (SPI) ----------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t SPCR;\r
+ __I uint32_t SPSR;\r
+ __IO uint32_t SPDR;\r
+ __IO uint32_t SPCCR;\r
+ uint32_t RESERVED0[3];\r
+ __IO uint32_t SPINT;\r
+} SPI_TypeDef;\r
+\r
+/*------------- Synchronous Serial Communication (SSP) -----------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t CR0;\r
+ __IO uint32_t CR1;\r
+ __IO uint32_t DR;\r
+ __I uint32_t SR;\r
+ __IO uint32_t CPSR;\r
+ __IO uint32_t IMSC;\r
+ __IO uint32_t RIS;\r
+ __IO uint32_t MIS;\r
+ __IO uint32_t ICR;\r
+ __IO uint32_t DMACR;\r
+} SSP_TypeDef;\r
+\r
+/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t I2CONSET;\r
+ __I uint32_t I2STAT;\r
+ __IO uint32_t I2DAT;\r
+ __IO uint32_t I2ADR0;\r
+ __IO uint32_t I2SCLH;\r
+ __IO uint32_t I2SCLL;\r
+ __O uint32_t I2CONCLR;\r
+ __IO uint32_t MMCTRL;\r
+ __IO uint32_t I2ADR1;\r
+ __IO uint32_t I2ADR2;\r
+ __IO uint32_t I2ADR3;\r
+ __I uint32_t I2DATA_BUFFER;\r
+ __IO uint32_t I2MASK0;\r
+ __IO uint32_t I2MASK1;\r
+ __IO uint32_t I2MASK2;\r
+ __IO uint32_t I2MASK3;\r
+} I2C_TypeDef;\r
+\r
+/*------------- Inter IC Sound (I2S) -----------------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t I2SDAO;\r
+ __IO uint32_t I2SDAI;\r
+ __O uint32_t I2STXFIFO;\r
+ __I uint32_t I2SRXFIFO;\r
+ __I uint32_t I2SSTATE;\r
+ __IO uint32_t I2SDMA1;\r
+ __IO uint32_t I2SDMA2;\r
+ __IO uint32_t I2SIRQ;\r
+ __IO uint32_t I2STXRATE;\r
+ __IO uint32_t I2SRXRATE;\r
+ __IO uint32_t I2STXBITRATE;\r
+ __IO uint32_t I2SRXBITRATE;\r
+ __IO uint32_t I2STXMODE;\r
+ __IO uint32_t I2SRXMODE;\r
+} I2S_TypeDef;\r
+\r
+/*------------- Repetitive Interrupt Timer (RIT) -----------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t RICOMPVAL;\r
+ __IO uint32_t RIMASK;\r
+ __IO uint8_t RICTRL;\r
+ uint8_t RESERVED0[3];\r
+ __IO uint32_t RICOUNTER;\r
+} RIT_TypeDef;\r
+\r
+/*------------- Real-Time Clock (RTC) ----------------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint8_t ILR;\r
+ uint8_t RESERVED0[3];\r
+ __IO uint8_t CCR;\r
+ uint8_t RESERVED1[3];\r
+ __IO uint8_t CIIR;\r
+ uint8_t RESERVED2[3];\r
+ __IO uint8_t AMR;\r
+ uint8_t RESERVED3[3];\r
+ __I uint32_t CTIME0;\r
+ __I uint32_t CTIME1;\r
+ __I uint32_t CTIME2;\r
+ __IO uint8_t SEC;\r
+ uint8_t RESERVED4[3];\r
+ __IO uint8_t MIN;\r
+ uint8_t RESERVED5[3];\r
+ __IO uint8_t HOUR;\r
+ uint8_t RESERVED6[3];\r
+ __IO uint8_t DOM;\r
+ uint8_t RESERVED7[3];\r
+ __IO uint8_t DOW;\r
+ uint8_t RESERVED8[3];\r
+ __IO uint16_t DOY;\r
+ uint16_t RESERVED9;\r
+ __IO uint8_t MONTH;\r
+ uint8_t RESERVED10[3];\r
+ __IO uint16_t YEAR;\r
+ uint16_t RESERVED11;\r
+ __IO uint32_t CALIBRATION;\r
+ __IO uint32_t GPREG0;\r
+ __IO uint32_t GPREG1;\r
+ __IO uint32_t GPREG2;\r
+ __IO uint32_t GPREG3;\r
+ __IO uint32_t GPREG4;\r
+ __IO uint8_t WAKEUPDIS;\r
+ uint8_t RESERVED12[3];\r
+ __IO uint8_t PWRCTRL;\r
+ uint8_t RESERVED13[3];\r
+ __IO uint8_t ALSEC;\r
+ uint8_t RESERVED14[3];\r
+ __IO uint8_t ALMIN;\r
+ uint8_t RESERVED15[3];\r
+ __IO uint8_t ALHOUR;\r
+ uint8_t RESERVED16[3];\r
+ __IO uint8_t ALDOM;\r
+ uint8_t RESERVED17[3];\r
+ __IO uint8_t ALDOW;\r
+ uint8_t RESERVED18[3];\r
+ __IO uint16_t ALDOY;\r
+ uint16_t RESERVED19;\r
+ __IO uint8_t ALMON;\r
+ uint8_t RESERVED20[3];\r
+ __IO uint16_t ALYEAR;\r
+ uint16_t RESERVED21;\r
+} RTC_TypeDef;\r
+\r
+/*------------- Watchdog Timer (WDT) -----------------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint8_t WDMOD;\r
+ uint8_t RESERVED0[3];\r
+ __IO uint32_t WDTC;\r
+ __O uint8_t WDFEED;\r
+ uint8_t RESERVED1[3];\r
+ __I uint32_t WDTV;\r
+ __IO uint32_t WDCLKSEL;\r
+} WDT_TypeDef;\r
+\r
+/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t ADCR;\r
+ __IO uint32_t ADGDR;\r
+ uint32_t RESERVED0;\r
+ __IO uint32_t ADINTEN;\r
+ __I uint32_t ADDR0;\r
+ __I uint32_t ADDR1;\r
+ __I uint32_t ADDR2;\r
+ __I uint32_t ADDR3;\r
+ __I uint32_t ADDR4;\r
+ __I uint32_t ADDR5;\r
+ __I uint32_t ADDR6;\r
+ __I uint32_t ADDR7;\r
+ __I uint32_t ADSTAT;\r
+ __IO uint32_t ADTRM;\r
+} ADC_TypeDef;\r
+\r
+/*------------- Digital-to-Analog Converter (DAC) ----------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t DACR;\r
+ __IO uint32_t DACCTRL;\r
+ __IO uint16_t DACCNTVAL;\r
+} DAC_TypeDef;\r
+\r
+/*------------- Motor Control Pulse-Width Modulation (MCPWM) -----------------*/\r
+typedef struct\r
+{\r
+ __I uint32_t MCCON;\r
+ __O uint32_t MCCON_SET;\r
+ __O uint32_t MCCON_CLR;\r
+ __I uint32_t MCCAPCON;\r
+ __O uint32_t MCCAPCON_SET;\r
+ __O uint32_t MCCAPCON_CLR;\r
+ __IO uint32_t MCTIM0;\r
+ __IO uint32_t MCTIM1;\r
+ __IO uint32_t MCTIM2;\r
+ __IO uint32_t MCPER0;\r
+ __IO uint32_t MCPER1;\r
+ __IO uint32_t MCPER2;\r
+ __IO uint32_t MCPW0;\r
+ __IO uint32_t MCPW1;\r
+ __IO uint32_t MCPW2;\r
+ __IO uint32_t MCDEADTIME;\r
+ __IO uint32_t MCCCP;\r
+ __IO uint32_t MCCR0;\r
+ __IO uint32_t MCCR1;\r
+ __IO uint32_t MCCR2;\r
+ __I uint32_t MCINTEN;\r
+ __O uint32_t MCINTEN_SET;\r
+ __O uint32_t MCINTEN_CLR;\r
+ __I uint32_t MCCNTCON;\r
+ __O uint32_t MCCNTCON_SET;\r
+ __O uint32_t MCCNTCON_CLR;\r
+ __I uint32_t MCINTFLAG;\r
+ __O uint32_t MCINTFLAG_SET;\r
+ __O uint32_t MCINTFLAG_CLR;\r
+ __O uint32_t MCCAP_CLR;\r
+} MCPWM_TypeDef;\r
+\r
+/*------------- Quadrature Encoder Interface (QEI) ---------------------------*/\r
+typedef struct\r
+{\r
+ __O uint32_t QEICON;\r
+ __I uint32_t QEISTAT;\r
+ __IO uint32_t QEICONF;\r
+ __I uint32_t QEIPOS;\r
+ __IO uint32_t QEIMAXPOS;\r
+ __IO uint32_t CMPOS0;\r
+ __IO uint32_t CMPOS1;\r
+ __IO uint32_t CMPOS2;\r
+ __I uint32_t INXCNT;\r
+ __IO uint32_t INXCMP;\r
+ __IO uint32_t QEILOAD;\r
+ __I uint32_t QEITIME;\r
+ __I uint32_t QEIVEL;\r
+ __I uint32_t QEICAP;\r
+ __IO uint32_t VELCOMP;\r
+ __IO uint32_t FILTER;\r
+ uint32_t RESERVED0[998];\r
+ __O uint32_t QEIIEC;\r
+ __O uint32_t QEIIES;\r
+ __I uint32_t QEIINTSTAT;\r
+ __I uint32_t QEIIE;\r
+ __O uint32_t QEICLR;\r
+ __O uint32_t QEISET;\r
+} QEI_TypeDef;\r
+\r
+/*------------- Controller Area Network (CAN) --------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t mask[512]; /* ID Masks */\r
+} CANAF_RAM_TypeDef;\r
+\r
+typedef struct /* Acceptance Filter Registers */\r
+{\r
+ __IO uint32_t AFMR;\r
+ __IO uint32_t SFF_sa;\r
+ __IO uint32_t SFF_GRP_sa;\r
+ __IO uint32_t EFF_sa;\r
+ __IO uint32_t EFF_GRP_sa;\r
+ __IO uint32_t ENDofTable;\r
+ __I uint32_t LUTerrAd;\r
+ __I uint32_t LUTerr;\r
+} CANAF_TypeDef;\r
+\r
+typedef struct /* Central Registers */\r
+{\r
+ __I uint32_t CANTxSR;\r
+ __I uint32_t CANRxSR;\r
+ __I uint32_t CANMSR;\r
+} CANCR_TypeDef;\r
+\r
+typedef struct /* Controller Registers */\r
+{\r
+ __IO uint32_t MOD;\r
+ __O uint32_t CMR;\r
+ __IO uint32_t GSR;\r
+ __I uint32_t ICR;\r
+ __IO uint32_t IER;\r
+ __IO uint32_t BTR;\r
+ __IO uint32_t EWL;\r
+ __I uint32_t SR;\r
+ __IO uint32_t RFS;\r
+ __IO uint32_t RID;\r
+ __IO uint32_t RDA;\r
+ __IO uint32_t RDB;\r
+ __IO uint32_t TFI1;\r
+ __IO uint32_t TID1;\r
+ __IO uint32_t TDA1;\r
+ __IO uint32_t TDB1;\r
+ __IO uint32_t TFI2;\r
+ __IO uint32_t TID2;\r
+ __IO uint32_t TDA2;\r
+ __IO uint32_t TDB2;\r
+ __IO uint32_t TFI3;\r
+ __IO uint32_t TID3;\r
+ __IO uint32_t TDA3;\r
+ __IO uint32_t TDB3;\r
+} CAN_TypeDef;\r
+\r
+/*------------- General Purpose Direct Memory Access (GPDMA) -----------------*/\r
+typedef struct /* Common Registers */\r
+{\r
+ __I uint32_t DMACIntStat;\r
+ __I uint32_t DMACIntTCStat;\r
+ __O uint32_t DMACIntTCClear;\r
+ __I uint32_t DMACIntErrStat;\r
+ __O uint32_t DMACIntErrClr;\r
+ __I uint32_t DMACRawIntTCStat;\r
+ __I uint32_t DMACRawIntErrStat;\r
+ __I uint32_t DMACEnbldChns;\r
+ __IO uint32_t DMACSoftBReq;\r
+ __IO uint32_t DMACSoftSReq;\r
+ __IO uint32_t DMACSoftLBReq;\r
+ __IO uint32_t DMACSoftLSReq;\r
+ __IO uint32_t DMACConfig;\r
+ __IO uint32_t DMACSync;\r
+} GPDMA_TypeDef;\r
+\r
+typedef struct /* Channel Registers */\r
+{\r
+ __IO uint32_t DMACCSrcAddr;\r
+ __IO uint32_t DMACCDestAddr;\r
+ __IO uint32_t DMACCLLI;\r
+ __IO uint32_t DMACCControl;\r
+ __IO uint32_t DMACCConfig;\r
+} GPDMACH_TypeDef;\r
+\r
+/*------------- Universal Serial Bus (USB) -----------------------------------*/\r
+typedef struct\r
+{\r
+ __I uint32_t HcRevision; /* USB Host Registers */\r
+ __IO uint32_t HcControl;\r
+ __IO uint32_t HcCommandStatus;\r
+ __IO uint32_t HcInterruptStatus;\r
+ __IO uint32_t HcInterruptEnable;\r
+ __IO uint32_t HcInterruptDisable;\r
+ __IO uint32_t HcHCCA;\r
+ __I uint32_t HcPeriodCurrentED;\r
+ __IO uint32_t HcControlHeadED;\r
+ __IO uint32_t HcControlCurrentED;\r
+ __IO uint32_t HcBulkHeadED;\r
+ __IO uint32_t HcBulkCurrentED;\r
+ __I uint32_t HcDoneHead;\r
+ __IO uint32_t HcFmInterval;\r
+ __I uint32_t HcFmRemaining;\r
+ __I uint32_t HcFmNumber;\r
+ __IO uint32_t HcPeriodicStart;\r
+ __IO uint32_t HcLSTreshold;\r
+ __IO uint32_t HcRhDescriptorA;\r
+ __IO uint32_t HcRhDescriptorB;\r
+ __IO uint32_t HcRhStatus;\r
+ __IO uint32_t HcRhPortStatus1;\r
+ __IO uint32_t HcRhPortStatus2;\r
+ uint32_t RESERVED0[40];\r
+ __I uint32_t Module_ID;\r
+\r
+ __I uint32_t OTGIntSt; /* USB On-The-Go Registers */\r
+ __IO uint32_t OTGIntEn;\r
+ __O uint32_t OTGIntSet;\r
+ __O uint32_t OTGIntClr;\r
+ __IO uint32_t OTGStCtrl;\r
+ __IO uint32_t OTGTmr;\r
+ uint32_t RESERVED1[58];\r
+\r
+ __I uint32_t USBDevIntSt; /* USB Device Interrupt Registers */\r
+ __IO uint32_t USBDevIntEn;\r
+ __O uint32_t USBDevIntClr;\r
+ __O uint32_t USBDevIntSet;\r
+\r
+ __O uint32_t USBCmdCode; /* USB Device SIE Command Registers */\r
+ __I uint32_t USBCmdData;\r
+\r
+ __I uint32_t USBRxData; /* USB Device Transfer Registers */\r
+ __O uint32_t USBTxData;\r
+ __I uint32_t USBRxPLen;\r
+ __O uint32_t USBTxPLen;\r
+ __IO uint32_t USBCtrl;\r
+ __O uint32_t USBDevIntPri;\r
+\r
+ __I uint32_t USBEpIntSt; /* USB Device Endpoint Interrupt Regs */\r
+ __IO uint32_t USBEpIntEn;\r
+ __O uint32_t USBEpIntClr;\r
+ __O uint32_t USBEpIntSet;\r
+ __O uint32_t USBEpIntPri;\r
+\r
+ __IO uint32_t USBReEp; /* USB Device Endpoint Realization Reg*/\r
+ __O uint32_t USBEpInd;\r
+ __IO uint32_t USBMaxPSize;\r
+\r
+ __I uint32_t USBDMARSt; /* USB Device DMA Registers */\r
+ __O uint32_t USBDMARClr;\r
+ __O uint32_t USBDMARSet;\r
+ uint32_t RESERVED2[9];\r
+ __IO uint32_t USBUDCAH;\r
+ __I uint32_t USBEpDMASt;\r
+ __O uint32_t USBEpDMAEn;\r
+ __O uint32_t USBEpDMADis;\r
+ __I uint32_t USBDMAIntSt;\r
+ __IO uint32_t USBDMAIntEn;\r
+ uint32_t RESERVED3[2];\r
+ __I uint32_t USBEoTIntSt;\r
+ __O uint32_t USBEoTIntClr;\r
+ __O uint32_t USBEoTIntSet;\r
+ __I uint32_t USBNDDRIntSt;\r
+ __O uint32_t USBNDDRIntClr;\r
+ __O uint32_t USBNDDRIntSet;\r
+ __I uint32_t USBSysErrIntSt;\r
+ __O uint32_t USBSysErrIntClr;\r
+ __O uint32_t USBSysErrIntSet;\r
+ uint32_t RESERVED4[15];\r
+\r
+ __I uint32_t I2C_RX; /* USB OTG I2C Registers */\r
+ __O uint32_t I2C_WO;\r
+ __I uint32_t I2C_STS;\r
+ __IO uint32_t I2C_CTL;\r
+ __IO uint32_t I2C_CLKHI;\r
+ __O uint32_t I2C_CLKLO;\r
+ uint32_t RESERVED5[823];\r
+\r
+ union {\r
+ __IO uint32_t USBClkCtrl; /* USB Clock Control Registers */\r
+ __IO uint32_t OTGClkCtrl;\r
+ } ;\r
+ union {\r
+ __I uint32_t USBClkSt;\r
+ __I uint32_t OTGClkSt;\r
+ };\r
+} USB_TypeDef;\r
+\r
+/*------------- Ethernet Media Access Controller (EMAC) ----------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t MAC1; /* MAC Registers */\r
+ __IO uint32_t MAC2;\r
+ __IO uint32_t IPGT;\r
+ __IO uint32_t IPGR;\r
+ __IO uint32_t CLRT;\r
+ __IO uint32_t MAXF;\r
+ __IO uint32_t SUPP;\r
+ __IO uint32_t TEST;\r
+ __IO uint32_t MCFG;\r
+ __IO uint32_t MCMD;\r
+ __IO uint32_t MADR;\r
+ __O uint32_t MWTD;\r
+ __I uint32_t MRDD;\r
+ __I uint32_t MIND;\r
+ uint32_t RESERVED0[2];\r
+ __IO uint32_t SA0;\r
+ __IO uint32_t SA1;\r
+ __IO uint32_t SA2;\r
+ uint32_t RESERVED1[45];\r
+ __IO uint32_t Command; /* Control Registers */\r
+ __I uint32_t Status;\r
+ __IO uint32_t RxDescriptor;\r
+ __IO uint32_t RxStatus;\r
+ __IO uint32_t RxDescriptorNumber;\r
+ __I uint32_t RxProduceIndex;\r
+ __IO uint32_t RxConsumeIndex;\r
+ __IO uint32_t TxDescriptor;\r
+ __IO uint32_t TxStatus;\r
+ __IO uint32_t TxDescriptorNumber;\r
+ __IO uint32_t TxProduceIndex;\r
+ __I uint32_t TxConsumeIndex;\r
+ uint32_t RESERVED2[10];\r
+ __I uint32_t TSV0;\r
+ __I uint32_t TSV1;\r
+ __I uint32_t RSV;\r
+ uint32_t RESERVED3[3];\r
+ __IO uint32_t FlowControlCounter;\r
+ __I uint32_t FlowControlStatus;\r
+ uint32_t RESERVED4[34];\r
+ __IO uint32_t RxFilterCtrl; /* Rx Filter Registers */\r
+ __IO uint32_t RxFilterWoLStatus;\r
+ __IO uint32_t RxFilterWoLClear;\r
+ uint32_t RESERVED5;\r
+ __IO uint32_t HashFilterL;\r
+ __IO uint32_t HashFilterH;\r
+ uint32_t RESERVED6[882];\r
+ __I uint32_t IntStatus; /* Module Control Registers */\r
+ __IO uint32_t IntEnable;\r
+ __O uint32_t IntClear;\r
+ __O uint32_t IntSet;\r
+ uint32_t RESERVED7;\r
+ __IO uint32_t PowerDown;\r
+ uint32_t RESERVED8;\r
+ __IO uint32_t Module_ID;\r
+} EMAC_TypeDef;\r
+\r
+\r
+/******************************************************************************/\r
+/* Peripheral memory map */\r
+/******************************************************************************/\r
+/* Base addresses */\r
+#define FLASH_BASE (0x00000000UL)\r
+#define RAM_BASE (0x10000000UL)\r
+#define GPIO_BASE (0x2009C000UL)\r
+#define APB0_BASE (0x40000000UL)\r
+#define APB1_BASE (0x40080000UL)\r
+#define AHB_BASE (0x50000000UL)\r
+#define CM3_BASE (0xE0000000UL)\r
+\r
+/* APB0 peripherals */\r
+#define WDT_BASE (APB0_BASE + 0x00000)\r
+#define TIM0_BASE (APB0_BASE + 0x04000)\r
+#define TIM1_BASE (APB0_BASE + 0x08000)\r
+#define UART0_BASE (APB0_BASE + 0x0C000)\r
+#define UART1_BASE (APB0_BASE + 0x10000)\r
+#define PWM1_BASE (APB0_BASE + 0x18000)\r
+#define I2C0_BASE (APB0_BASE + 0x1C000)\r
+#define SPI_BASE (APB0_BASE + 0x20000)\r
+#define RTC_BASE (APB0_BASE + 0x24000)\r
+#define GPIOINT_BASE (APB0_BASE + 0x28080)\r
+#define PINCON_BASE (APB0_BASE + 0x2C000)\r
+#define SSP1_BASE (APB0_BASE + 0x30000)\r
+#define ADC_BASE (APB0_BASE + 0x34000)\r
+#define CANAF_RAM_BASE (APB0_BASE + 0x38000)\r
+#define CANAF_BASE (APB0_BASE + 0x3C000)\r
+#define CANCR_BASE (APB0_BASE + 0x40000)\r
+#define CAN1_BASE (APB0_BASE + 0x44000)\r
+#define CAN2_BASE (APB0_BASE + 0x48000)\r
+#define I2C1_BASE (APB0_BASE + 0x5C000)\r
+\r
+/* APB1 peripherals */\r
+#define SSP0_BASE (APB1_BASE + 0x08000)\r
+#define DAC_BASE (APB1_BASE + 0x0C000)\r
+#define TIM2_BASE (APB1_BASE + 0x10000)\r
+#define TIM3_BASE (APB1_BASE + 0x14000)\r
+#define UART2_BASE (APB1_BASE + 0x18000)\r
+#define UART3_BASE (APB1_BASE + 0x1C000)\r
+#define I2C2_BASE (APB1_BASE + 0x20000)\r
+#define I2S_BASE (APB1_BASE + 0x28000)\r
+#define RIT_BASE (APB1_BASE + 0x30000)\r
+#define MCPWM_BASE (APB1_BASE + 0x38000)\r
+#define QEI_BASE (APB1_BASE + 0x3C000)\r
+#define SC_BASE (APB1_BASE + 0x7C000)\r
+\r
+/* AHB peripherals */\r
+#define EMAC_BASE (AHB_BASE + 0x00000)\r
+#define GPDMA_BASE (AHB_BASE + 0x04000)\r
+#define GPDMACH0_BASE (AHB_BASE + 0x04100)\r
+#define GPDMACH1_BASE (AHB_BASE + 0x04120)\r
+#define GPDMACH2_BASE (AHB_BASE + 0x04140)\r
+#define GPDMACH3_BASE (AHB_BASE + 0x04160)\r
+#define GPDMACH4_BASE (AHB_BASE + 0x04180)\r
+#define GPDMACH5_BASE (AHB_BASE + 0x041A0)\r
+#define GPDMACH6_BASE (AHB_BASE + 0x041C0)\r
+#define GPDMACH7_BASE (AHB_BASE + 0x041E0)\r
+#define USB_BASE (AHB_BASE + 0x0C000)\r
+\r
+/* GPIOs */\r
+#define GPIO0_BASE (GPIO_BASE + 0x00000)\r
+#define GPIO1_BASE (GPIO_BASE + 0x00020)\r
+#define GPIO2_BASE (GPIO_BASE + 0x00040)\r
+#define GPIO3_BASE (GPIO_BASE + 0x00060)\r
+#define GPIO4_BASE (GPIO_BASE + 0x00080)\r
+\r
+\r
+/******************************************************************************/\r
+/* Peripheral declaration */\r
+/******************************************************************************/\r
+#define SC (( SC_TypeDef *) SC_BASE)\r
+#define GPIO0 (( GPIO_TypeDef *) GPIO0_BASE)\r
+#define GPIO1 (( GPIO_TypeDef *) GPIO1_BASE)\r
+#define GPIO2 (( GPIO_TypeDef *) GPIO2_BASE)\r
+#define GPIO3 (( GPIO_TypeDef *) GPIO3_BASE)\r
+#define GPIO4 (( GPIO_TypeDef *) GPIO4_BASE)\r
+#define WDT (( WDT_TypeDef *) WDT_BASE)\r
+#define TIM0 (( TIM_TypeDef *) TIM0_BASE)\r
+#define TIM1 (( TIM_TypeDef *) TIM1_BASE)\r
+#define TIM2 (( TIM_TypeDef *) TIM2_BASE)\r
+#define TIM3 (( TIM_TypeDef *) TIM3_BASE)\r
+#define RIT (( RIT_TypeDef *) RIT_BASE)\r
+#define UART0 (( UART_TypeDef *) UART0_BASE)\r
+#define UART1 (( UART1_TypeDef *) UART1_BASE)\r
+#define UART2 (( UART_TypeDef *) UART2_BASE)\r
+#define UART3 (( UART_TypeDef *) UART3_BASE)\r
+#define PWM1 (( PWM_TypeDef *) PWM1_BASE)\r
+#define I2C0 (( I2C_TypeDef *) I2C0_BASE)\r
+#define I2C1 (( I2C_TypeDef *) I2C1_BASE)\r
+#define I2C2 (( I2C_TypeDef *) I2C2_BASE)\r
+#define I2S (( I2S_TypeDef *) I2S_BASE)\r
+#define SPI (( SPI_TypeDef *) SPI_BASE)\r
+#define RTC (( RTC_TypeDef *) RTC_BASE)\r
+#define GPIOINT (( GPIOINT_TypeDef *) GPIOINT_BASE)\r
+#define PINCON (( PINCON_TypeDef *) PINCON_BASE)\r
+#define SSP0 (( SSP_TypeDef *) SSP0_BASE)\r
+#define SSP1 (( SSP_TypeDef *) SSP1_BASE)\r
+#define ADC (( ADC_TypeDef *) ADC_BASE)\r
+#define DAC (( DAC_TypeDef *) DAC_BASE)\r
+#define CANAF_RAM ((CANAF_RAM_TypeDef *) CANAF_RAM_BASE)\r
+#define CANAF (( CANAF_TypeDef *) CANAF_BASE)\r
+#define CANCR (( CANCR_TypeDef *) CANCR_BASE)\r
+#define CAN1 (( CAN_TypeDef *) CAN1_BASE)\r
+#define CAN2 (( CAN_TypeDef *) CAN2_BASE)\r
+#define MCPWM (( MCPWM_TypeDef *) MCPWM_BASE)\r
+#define QEI (( QEI_TypeDef *) QEI_BASE)\r
+#define EMAC (( EMAC_TypeDef *) EMAC_BASE)\r
+#define GPDMA (( GPDMA_TypeDef *) GPDMA_BASE)\r
+#define GPDMACH0 (( GPDMACH_TypeDef *) GPDMACH0_BASE)\r
+#define GPDMACH1 (( GPDMACH_TypeDef *) GPDMACH1_BASE)\r
+#define GPDMACH2 (( GPDMACH_TypeDef *) GPDMACH2_BASE)\r
+#define GPDMACH3 (( GPDMACH_TypeDef *) GPDMACH3_BASE)\r
+#define GPDMACH4 (( GPDMACH_TypeDef *) GPDMACH4_BASE)\r
+#define GPDMACH5 (( GPDMACH_TypeDef *) GPDMACH5_BASE)\r
+#define GPDMACH6 (( GPDMACH_TypeDef *) GPDMACH6_BASE)\r
+#define GPDMACH7 (( GPDMACH_TypeDef *) GPDMACH7_BASE)\r
+#define USB (( USB_TypeDef *) USB_BASE)\r
+\r
+#endif // __LPC17xx_H__\r
+\r
+\r
+#endif\r
--- /dev/null
+/*\r
+ LPCUSB, an USB device driver for LPC microcontrollers\r
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)\r
+\r
+ Redistribution and use in source and binary forms, with or without\r
+ modification, are permitted provided that the following conditions are met:\r
+\r
+ 1. Redistributions of source code must retain the above copyright\r
+ notice, this list of conditions and the following disclaimer.\r
+ 2. Redistributions in binary form must reproduce the above copyright\r
+ notice, this list of conditions and the following disclaimer in the\r
+ documentation and/or other materials provided with the distribution.\r
+ 3. The name of the author may not be used to endorse or promote products\r
+ derived from this software without specific prior written permission.\r
+\r
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*/\r
+\r
+/*\r
+ Minimal implementation of a USB serial port, using the CDC class.\r
+ This example application simply echoes everything it receives right back\r
+ to the host.\r
+\r
+ Windows:\r
+ Extract the usbser.sys file from .cab file in C:\WINDOWS\Driver Cache\i386\r
+ and store it somewhere (C:\temp is a good place) along with the usbser.inf\r
+ file. Then plug in the LPC176x and direct windows to the usbser driver.\r
+ Windows then creates an extra COMx port that you can open in a terminal\r
+ program, like hyperterminal. [Note for FreeRTOS users - the required .inf\r
+ file is included in the project directory.]\r
+\r
+ Linux:\r
+ The device should be recognised automatically by the cdc_acm driver,\r
+ which creates a /dev/ttyACMx device file that acts just like a regular\r
+ serial port.\r
+\r
+*/\r
+\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "usbapi.h"\r
+#include "usbdebug.h"\r
+#include "usbstruct.h"\r
+\r
+#include "LPC17xx.h"\r
+\r
+#define usbMAX_SEND_BLOCK ( 20 / portTICK_RATE_MS )\r
+#define usbBUFFER_LEN ( 20 )\r
+\r
+#define INCREMENT_ECHO_BY 1\r
+#define BAUD_RATE 115200\r
+\r
+#define INT_IN_EP 0x81\r
+#define BULK_OUT_EP 0x05\r
+#define BULK_IN_EP 0x82\r
+\r
+#define MAX_PACKET_SIZE 64\r
+\r
+#define LE_WORD(x) ((x)&0xFF),((x)>>8)\r
+\r
+// CDC definitions\r
+#define CS_INTERFACE 0x24\r
+#define CS_ENDPOINT 0x25\r
+\r
+#define SET_LINE_CODING 0x20\r
+#define GET_LINE_CODING 0x21\r
+#define SET_CONTROL_LINE_STATE 0x22\r
+\r
+// data structure for GET_LINE_CODING / SET_LINE_CODING class requests\r
+typedef struct {\r
+ unsigned long dwDTERate;\r
+ unsigned char bCharFormat;\r
+ unsigned char bParityType;\r
+ unsigned char bDataBits;\r
+} TLineCoding;\r
+\r
+static TLineCoding LineCoding = {115200, 0, 0, 8};\r
+static unsigned char abBulkBuf[64];\r
+static unsigned char abClassReqData[8];\r
+\r
+static xQueueHandle xRxedChars = NULL, xCharsForTx = NULL;\r
+\r
+// forward declaration of interrupt handler\r
+void USBIntHandler(void);\r
+\r
+static const unsigned char abDescriptors[] = {\r
+\r
+// device descriptor\r
+ 0x12,\r
+ DESC_DEVICE,\r
+ LE_WORD(0x0101), // bcdUSB\r
+ 0x02, // bDeviceClass\r
+ 0x00, // bDeviceSubClass\r
+ 0x00, // bDeviceProtocol\r
+ MAX_PACKET_SIZE0, // bMaxPacketSize\r
+ LE_WORD(0xFFFF), // idVendor\r
+ LE_WORD(0x0005), // idProduct\r
+ LE_WORD(0x0100), // bcdDevice\r
+ 0x01, // iManufacturer\r
+ 0x02, // iProduct\r
+ 0x03, // iSerialNumber\r
+ 0x01, // bNumConfigurations\r
+\r
+// configuration descriptor\r
+ 0x09,\r
+ DESC_CONFIGURATION,\r
+ LE_WORD(67), // wTotalLength\r
+ 0x02, // bNumInterfaces\r
+ 0x01, // bConfigurationValue\r
+ 0x00, // iConfiguration\r
+ 0xC0, // bmAttributes\r
+ 0x32, // bMaxPower\r
+// control class interface\r
+ 0x09,\r
+ DESC_INTERFACE,\r
+ 0x00, // bInterfaceNumber\r
+ 0x00, // bAlternateSetting\r
+ 0x01, // bNumEndPoints\r
+ 0x02, // bInterfaceClass\r
+ 0x02, // bInterfaceSubClass\r
+ 0x01, // bInterfaceProtocol, linux requires value of 1 for the cdc_acm module\r
+ 0x00, // iInterface\r
+// header functional descriptor\r
+ 0x05,\r
+ CS_INTERFACE,\r
+ 0x00,\r
+ LE_WORD(0x0110),\r
+// call management functional descriptor\r
+ 0x05,\r
+ CS_INTERFACE,\r
+ 0x01,\r
+ 0x01, // bmCapabilities = device handles call management\r
+ 0x01, // bDataInterface\r
+// ACM functional descriptor\r
+ 0x04,\r
+ CS_INTERFACE,\r
+ 0x02,\r
+ 0x02, // bmCapabilities\r
+// union functional descriptor\r
+ 0x05,\r
+ CS_INTERFACE,\r
+ 0x06,\r
+ 0x00, // bMasterInterface\r
+ 0x01, // bSlaveInterface0\r
+// notification EP\r
+ 0x07,\r
+ DESC_ENDPOINT,\r
+ INT_IN_EP, // bEndpointAddress\r
+ 0x03, // bmAttributes = intr\r
+ LE_WORD(8), // wMaxPacketSize\r
+ 0x0A, // bInterval\r
+// data class interface descriptor\r
+ 0x09,\r
+ DESC_INTERFACE,\r
+ 0x01, // bInterfaceNumber\r
+ 0x00, // bAlternateSetting\r
+ 0x02, // bNumEndPoints\r
+ 0x0A, // bInterfaceClass = data\r
+ 0x00, // bInterfaceSubClass\r
+ 0x00, // bInterfaceProtocol\r
+ 0x00, // iInterface\r
+// data EP OUT\r
+ 0x07,\r
+ DESC_ENDPOINT,\r
+ BULK_OUT_EP, // bEndpointAddress\r
+ 0x02, // bmAttributes = bulk\r
+ LE_WORD(MAX_PACKET_SIZE), // wMaxPacketSize\r
+ 0x00, // bInterval\r
+// data EP in\r
+ 0x07,\r
+ DESC_ENDPOINT,\r
+ BULK_IN_EP, // bEndpointAddress\r
+ 0x02, // bmAttributes = bulk\r
+ LE_WORD(MAX_PACKET_SIZE), // wMaxPacketSize\r
+ 0x00, // bInterval\r
+\r
+ // string descriptors\r
+ 0x04,\r
+ DESC_STRING,\r
+ LE_WORD(0x0409),\r
+\r
+ 0x0E,\r
+ DESC_STRING,\r
+ 'L', 0, 'P', 0, 'C', 0, 'U', 0, 'S', 0, 'B', 0,\r
+\r
+ 0x14,\r
+ DESC_STRING,\r
+ 'U', 0, 'S', 0, 'B', 0, 'S', 0, 'e', 0, 'r', 0, 'i', 0, 'a', 0, 'l', 0,\r
+\r
+ 0x12,\r
+ DESC_STRING,\r
+ 'D', 0, 'E', 0, 'A', 0, 'D', 0, 'C', 0, '0', 0, 'D', 0, 'E', 0,\r
+\r
+// terminating zero\r
+ 0\r
+};\r
+\r
+\r
+/**\r
+ Local function to handle incoming bulk data\r
+\r
+ @param [in] bEP\r
+ @param [in] bEPStatus\r
+ */\r
+static void BulkOut(unsigned char bEP, unsigned char bEPStatus)\r
+{\r
+ int i, iLen;\r
+ long lHigherPriorityTaskWoken = pdFALSE;\r
+\r
+ ( void ) bEPStatus;\r
+\r
+ // get data from USB into intermediate buffer\r
+ iLen = USBHwEPRead(bEP, abBulkBuf, sizeof(abBulkBuf));\r
+ for (i = 0; i < iLen; i++) {\r
+ // put into queue\r
+ xQueueSendFromISR( xRxedChars, &( abBulkBuf[ i ] ), &lHigherPriorityTaskWoken );\r
+ }\r
+\r
+ portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );\r
+}\r
+\r
+\r
+/**\r
+ Local function to handle outgoing bulk data\r
+\r
+ @param [in] bEP\r
+ @param [in] bEPStatus\r
+ */\r
+static void BulkIn(unsigned char bEP, unsigned char bEPStatus)\r
+{\r
+ int i, iLen;\r
+ long lHigherPriorityTaskWoken = pdFALSE;\r
+\r
+ ( void ) bEPStatus;\r
+\r
+ if (uxQueueMessagesWaitingFromISR( xCharsForTx ) == 0) {\r
+ // no more data, disable further NAK interrupts until next USB frame\r
+ USBHwNakIntEnable(0);\r
+ return;\r
+ }\r
+\r
+ // get bytes from transmit FIFO into intermediate buffer\r
+ for (i = 0; i < MAX_PACKET_SIZE; i++) {\r
+ if( xQueueReceiveFromISR( xCharsForTx, ( &abBulkBuf[i] ), &lHigherPriorityTaskWoken ) != pdPASS )\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ iLen = i;\r
+\r
+ // send over USB\r
+ if (iLen > 0) {\r
+ USBHwEPWrite(bEP, abBulkBuf, iLen);\r
+ }\r
+\r
+ portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );\r
+}\r
+\r
+\r
+/**\r
+ Local function to handle the USB-CDC class requests\r
+\r
+ @param [in] pSetup\r
+ @param [out] piLen\r
+ @param [out] ppbData\r
+ */\r
+static BOOL HandleClassRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)\r
+{\r
+ switch (pSetup->bRequest) {\r
+\r
+ // set line coding\r
+ case SET_LINE_CODING:\r
+DBG("SET_LINE_CODING\n");\r
+ memcpy((unsigned char *)&LineCoding, *ppbData, 7);\r
+ *piLen = 7;\r
+DBG("dwDTERate=%u, bCharFormat=%u, bParityType=%u, bDataBits=%u\n",\r
+ LineCoding.dwDTERate,\r
+ LineCoding.bCharFormat,\r
+ LineCoding.bParityType,\r
+ LineCoding.bDataBits);\r
+ break;\r
+\r
+ // get line coding\r
+ case GET_LINE_CODING:\r
+DBG("GET_LINE_CODING\n");\r
+ *ppbData = (unsigned char *)&LineCoding;\r
+ *piLen = 7;\r
+ break;\r
+\r
+ // set control line state\r
+ case SET_CONTROL_LINE_STATE:\r
+ // bit0 = DTR, bit = RTS\r
+DBG("SET_CONTROL_LINE_STATE %X\n", pSetup->wValue);\r
+ break;\r
+\r
+ default:\r
+ return FALSE;\r
+ }\r
+ return TRUE;\r
+}\r
+\r
+\r
+/**\r
+ Writes one character to VCOM port\r
+\r
+ @param [in] c character to write\r
+ @returns character written, or EOF if character could not be written\r
+ */\r
+int VCOM_putchar(int c)\r
+{\r
+char cc = ( char ) c;\r
+\r
+ if( xQueueSend( xCharsForTx, &cc, usbMAX_SEND_BLOCK ) == pdPASS )\r
+ {\r
+ return c;\r
+ }\r
+ else\r
+ {\r
+ return EOF;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ Reads one character from VCOM port\r
+\r
+ @returns character read, or EOF if character could not be read\r
+ */\r
+int VCOM_getchar(void)\r
+{\r
+ unsigned char c;\r
+\r
+ /* Block the task until a character is available. */\r
+ xQueueReceive( xRxedChars, &c, portMAX_DELAY );\r
+ return c;\r
+}\r
+\r
+\r
+/**\r
+ Interrupt handler\r
+\r
+ Simply calls the USB ISR\r
+ */\r
+//void USBIntHandler(void)\r
+void USB_IRQHandler(void)\r
+{\r
+ USBHwISR();\r
+}\r
+\r
+\r
+static void USBFrameHandler(unsigned short wFrame)\r
+{\r
+ ( void ) wFrame;\r
+\r
+ if( uxQueueMessagesWaitingFromISR( xCharsForTx ) > 0 )\r
+ {\r
+ // data available, enable NAK interrupt on bulk in\r
+ USBHwNakIntEnable(INACK_BI);\r
+ }\r
+}\r
+\r
+// CodeRed - added CPUcpsie\r
+\r
+unsigned long CPUcpsie(void)\r
+{\r
+ unsigned long ulRet;\r
+\r
+ //\r
+ // Read PRIMASK and enable interrupts.\r
+ //\r
+ __asm(" mrs %0, PRIMASK\n"\r
+ " cpsie i\n"\r
+ " bx lr\n"\r
+ : "=r" (ulRet));\r
+\r
+ //\r
+ // The return is handled in the inline assembly, but the compiler will\r
+ // still complain if there is not an explicit return here (despite the fact\r
+ // that this does not result in any code being produced because of the\r
+ // naked attribute).\r
+ //\r
+ return(ulRet);\r
+}\r
+\r
+void vUSBTask( void *pvParameters )\r
+{\r
+ int c;\r
+\r
+ /* Just to prevent compiler warnings about the unused parameter. */\r
+ ( void ) pvParameters;\r
+ DBG("Initialising USB stack\n");\r
+\r
+ xRxedChars = xQueueCreate( usbBUFFER_LEN, sizeof( char ) );\r
+ xCharsForTx = xQueueCreate( usbBUFFER_LEN, sizeof( char ) );\r
+\r
+ if( ( xRxedChars == NULL ) || ( xCharsForTx == NULL ) )\r
+ {\r
+ /* Not enough heap available to create the buffer queues, can't do\r
+ anything so just delete ourselves. */\r
+ vTaskDelete( NULL );\r
+ }\r
+\r
+\r
+ // initialise stack\r
+ USBInit();\r
+\r
+ // register descriptors\r
+ USBRegisterDescriptors(abDescriptors);\r
+\r
+ // register class request handler\r
+ USBRegisterRequestHandler(REQTYPE_TYPE_CLASS, HandleClassRequest, abClassReqData);\r
+\r
+ // register endpoint handlers\r
+ USBHwRegisterEPIntHandler(INT_IN_EP, NULL);\r
+ USBHwRegisterEPIntHandler(BULK_IN_EP, BulkIn);\r
+ USBHwRegisterEPIntHandler(BULK_OUT_EP, BulkOut);\r
+\r
+ // register frame handler\r
+ USBHwRegisterFrameHandler(USBFrameHandler);\r
+\r
+ // enable bulk-in interrupts on NAKs\r
+ USBHwNakIntEnable(INACK_BI);\r
+\r
+ DBG("Starting USB communication\n");\r
+\r
+ NVIC_SetPriority( USB_IRQn, configUSB_INTERRUPT_PRIORITY );\r
+ NVIC_EnableIRQ( USB_IRQn );\r
+\r
+ // connect to bus\r
+\r
+ DBG("Connecting to USB bus\n");\r
+ USBHwConnect(TRUE);\r
+\r
+ // echo any character received (do USB stuff in interrupt)\r
+ for( ;; )\r
+ {\r
+ c = VCOM_getchar();\r
+ if (c != EOF)\r
+ {\r
+ // Echo character back with INCREMENT_ECHO_BY offset, so for example if\r
+ // INCREMENT_ECHO_BY is 1 and 'A' is received, 'B' will be echoed back.\r
+ VCOM_putchar(c + INCREMENT_ECHO_BY );\r
+ }\r
+ }\r
+}\r
+\r
--- /dev/null
+/*****************************************************************************\r
+ * type.h: Type definition Header file for NXP LPC17xx Family \r
+ * Microprocessors\r
+ *\r
+ * Copyright(C) 2008, NXP Semiconductor\r
+ * All rights reserved.\r
+ *\r
+ * History\r
+ * 2008.08.21 ver 1.00 Prelimnary version, first Release\r
+ *\r
+******************************************************************************/\r
+#ifndef __TYPE_H__\r
+#define __TYPE_H__\r
+\r
+#ifndef NULL\r
+#define NULL ((void *)0)\r
+#endif\r
+\r
+#ifndef FALSE\r
+#define FALSE (0)\r
+#endif\r
+\r
+#ifndef TRUE\r
+#define TRUE (1)\r
+#endif\r
+\r
+typedef unsigned char BYTE;\r
+typedef unsigned short WORD;\r
+typedef unsigned long DWORD;\r
+typedef unsigned int BOOL;\r
+\r
+typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;\r
+typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;\r
+\r
+/* Pointer to Function returning Void (any number of parameters) */\r
+typedef void (*PFV)();\r
+\r
+#endif /* __TYPE_H__ */\r
--- /dev/null
+/*\r
+ LPCUSB, an USB device driver for LPC microcontrollers \r
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)\r
+\r
+ Redistribution and use in source and binary forms, with or without\r
+ modification, are permitted provided that the following conditions are met:\r
+\r
+ 1. Redistributions of source code must retain the above copyright\r
+ notice, this list of conditions and the following disclaimer.\r
+ 2. Redistributions in binary form must reproduce the above copyright\r
+ notice, this list of conditions and the following disclaimer in the\r
+ documentation and/or other materials provided with the distribution.\r
+ 3. The name of the author may not be used to endorse or promote products\r
+ derived from this software without specific prior written permission.\r
+\r
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*/\r
+\r
+/**\r
+ @file\r
+*/\r
+\r
+#include "usbstruct.h" // for TSetupPacket\r
+\r
+/*************************************************************************\r
+ USB configuration\r
+**************************************************************************/\r
+\r
+#define MAX_PACKET_SIZE0 64 /**< maximum packet size for EP 0 */\r
+\r
+/*************************************************************************\r
+ USB hardware interface\r
+**************************************************************************/\r
+\r
+// endpoint status sent through callback\r
+#define EP_STATUS_DATA (1<<0) /**< EP has data */\r
+#define EP_STATUS_STALLED (1<<1) /**< EP is stalled */\r
+#define EP_STATUS_SETUP (1<<2) /**< EP received setup packet */\r
+#define EP_STATUS_ERROR (1<<3) /**< EP data was overwritten by setup packet */\r
+#define EP_STATUS_NACKED (1<<4) /**< EP sent NAK */\r
+\r
+// device status sent through callback\r
+#define DEV_STATUS_CONNECT (1<<0) /**< device just got connected */\r
+#define DEV_STATUS_SUSPEND (1<<2) /**< device entered suspend state */\r
+#define DEV_STATUS_RESET (1<<4) /**< device just got reset */\r
+\r
+// interrupt bits for NACK events in USBHwNakIntEnable\r
+// (these bits conveniently coincide with the LPC176x USB controller bit)\r
+#define INACK_CI (1<<1) /**< interrupt on NACK for control in */\r
+#define INACK_CO (1<<2) /**< interrupt on NACK for control out */\r
+#define INACK_II (1<<3) /**< interrupt on NACK for interrupt in */\r
+#define INACK_IO (1<<4) /**< interrupt on NACK for interrupt out */\r
+#define INACK_BI (1<<5) /**< interrupt on NACK for bulk in */\r
+#define INACK_BO (1<<6) /**< interrupt on NACK for bulk out */\r
+\r
+BOOL USBHwInit (void);\r
+void USBHwISR (void);\r
+\r
+void USBHwNakIntEnable (unsigned char bIntBits);\r
+\r
+void USBHwConnect (BOOL fConnect);\r
+\r
+void USBHwSetAddress (unsigned char bAddr);\r
+void USBHwConfigDevice (BOOL fConfigured);\r
+\r
+// endpoint operations\r
+void USBHwEPConfig (unsigned char bEP, unsigned short wMaxPacketSize);\r
+int USBHwEPRead (unsigned char bEP, unsigned char *pbBuf, int iMaxLen);\r
+int USBHwEPWrite (unsigned char bEP, unsigned char *pbBuf, int iLen);\r
+void USBHwEPStall (unsigned char bEP, BOOL fStall);\r
+unsigned char USBHwEPGetStatus (unsigned char bEP);\r
+\r
+/** Endpoint interrupt handler callback */\r
+typedef void (TFnEPIntHandler) (unsigned char bEP, unsigned char bEPStatus);\r
+void USBHwRegisterEPIntHandler (unsigned char bEP, TFnEPIntHandler *pfnHandler);\r
+\r
+/** Device status handler callback */\r
+typedef void (TFnDevIntHandler) (unsigned char bDevStatus);\r
+void USBHwRegisterDevIntHandler (TFnDevIntHandler *pfnHandler);\r
+\r
+/** Frame event handler callback */\r
+typedef void (TFnFrameHandler)(unsigned short wFrame);\r
+void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler);\r
+\r
+\r
+/*************************************************************************\r
+ USB application interface\r
+**************************************************************************/\r
+\r
+// initialise the complete stack, including HW\r
+BOOL USBInit(void);\r
+\r
+/** Request handler callback (standard, vendor, class) */\r
+typedef BOOL (TFnHandleRequest)(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData);\r
+void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, unsigned char *pbDataStore);\r
+void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler);\r
+\r
+/** Descriptor handler callback */\r
+typedef BOOL (TFnGetDescriptor)(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData);\r
+\r
+/** Default standard request handler */\r
+BOOL USBHandleStandardRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData);\r
+\r
+/** Default EP0 handler */\r
+void USBHandleControlTransfer(unsigned char bEP, unsigned char bEPStat);\r
+\r
+/** Descriptor handling */\r
+void USBRegisterDescriptors(const unsigned char *pabDescriptors);\r
+BOOL USBGetDescriptor(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData);\r
--- /dev/null
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/** @file
+ Control transfer handler.
+
+ This module handles control transfers and is normally installed on the
+ endpoint 0 callback.
+
+ Control transfers can be of the following type:
+ 0 Standard;
+ 1 Class;
+ 2 Vendor;
+ 3 Reserved.
+
+ A callback can be installed for each of these control transfers using
+ USBRegisterRequestHandler.
+ When an OUT request arrives, data is collected in the data store provided
+ with the USBRegisterRequestHandler call. When the transfer is done, the
+ callback is called.
+ When an IN request arrives, the callback is called immediately to either
+ put the control transfer data in the data store, or to get a pointer to
+ control transfer data. The data is then packetised and sent to the host.
+*/
+
+#include "usbdebug.h"
+
+#include "usbstruct.h"
+#include "usbapi.h"
+
+
+
+#define MAX_CONTROL_SIZE 128 /**< maximum total size of control transfer data */
+#define MAX_REQ_HANDLERS 4 /**< standard, class, vendor, reserved */
+
+static TSetupPacket Setup; /**< setup packet */
+
+static unsigned char *pbData; /**< pointer to data buffer */
+static int iResidue; /**< remaining bytes in buffer */
+static int iLen; /**< total length of control transfer */
+
+/** Array of installed request handler callbacks */
+static TFnHandleRequest *apfnReqHandlers[4] = {NULL, NULL, NULL, NULL};
+/** Array of installed request data pointers */
+static unsigned char *apbDataStore[4] = {NULL, NULL, NULL, NULL};
+
+/**
+ Local function to handle a request by calling one of the installed
+ request handlers.
+
+ In case of data going from host to device, the data is at *ppbData.
+ In case of data going from device to host, the handler can either
+ choose to write its data at *ppbData or update the data pointer.
+
+ @param [in] pSetup The setup packet
+ @param [in,out] *piLen Pointer to data length
+ @param [in,out] ppbData Data buffer.
+
+ @return TRUE if the request was handles successfully
+ */
+static BOOL _HandleRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)
+{
+ TFnHandleRequest *pfnHandler;
+ int iType;
+
+ iType = REQTYPE_GET_TYPE(pSetup->bmRequestType);
+ pfnHandler = apfnReqHandlers[iType];
+ if (pfnHandler == NULL) {
+ DBG("No handler for reqtype %d\n", iType);
+ return FALSE;
+ }
+
+ return pfnHandler(pSetup, piLen, ppbData);
+}
+
+
+/**
+ Local function to stall the control endpoint
+
+ @param [in] bEPStat Endpoint status
+ */
+static void StallControlPipe(unsigned char bEPStat)
+{
+ unsigned char *pb;
+ int i;
+
+ ( void ) bEPStat;
+ USBHwEPStall(0x80, TRUE);
+
+// dump setup packet
+ DBG("STALL on [");
+ pb = (unsigned char *)&Setup;
+ for (i = 0; i < 8; i++) {
+ DBG(" %02x", *pb++);
+ }
+ DBG("] stat=%x\n", bEPStat);
+}
+
+
+/**
+ Sends next chunk of data (possibly 0 bytes) to host
+ */
+static void DataIn(void)
+{
+ int iChunk;
+
+ if( MAX_PACKET_SIZE0 < iResidue )
+ {
+ iChunk = MAX_PACKET_SIZE0;
+ }
+ else
+ {
+ iChunk = iResidue;
+ }
+
+ USBHwEPWrite(0x80, pbData, iChunk);
+ pbData += iChunk;
+ iResidue -= iChunk;
+}
+
+
+/**
+ * Handles IN/OUT transfers on EP0
+ *
+ * @param [in] bEP Endpoint address
+ * @param [in] bEPStat Endpoint status
+ */
+void USBHandleControlTransfer(unsigned char bEP, unsigned char bEPStat)
+{
+ int iChunk, iType;
+
+ if (bEP == 0x00) {
+ // OUT transfer
+ if (bEPStat & EP_STATUS_SETUP) {
+ // setup packet, reset request message state machine
+ USBHwEPRead(0x00, (unsigned char *)&Setup, sizeof(Setup));
+ DBG("S%x", Setup.bRequest);
+
+ // defaults for data pointer and residue
+ iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
+ pbData = apbDataStore[iType];
+ iResidue = Setup.wLength;
+ iLen = Setup.wLength;
+
+ if ((Setup.wLength == 0) ||
+ (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) {
+ // ask installed handler to process request
+ if (!_HandleRequest(&Setup, &iLen, &pbData)) {
+ DBG("_HandleRequest1 failed\n");
+ StallControlPipe(bEPStat);
+ return;
+ }
+ // send smallest of requested and offered length
+ if( iLen < Setup.wLength )
+ {
+ iResidue = iLen;
+ }
+ else
+ {
+ iResidue = Setup.wLength;
+ }
+
+ // send first part (possibly a zero-length status message)
+ DataIn();
+ }
+ }
+ else {
+ if (iResidue > 0) {
+ // store data
+ iChunk = USBHwEPRead(0x00, pbData, iResidue);
+ if (iChunk < 0) {
+ StallControlPipe(bEPStat);
+ return;
+ }
+ pbData += iChunk;
+ iResidue -= iChunk;
+ if (iResidue == 0) {
+ // received all, send data to handler
+ iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
+ pbData = apbDataStore[iType];
+ if (!_HandleRequest(&Setup, &iLen, &pbData)) {
+ DBG("_HandleRequest2 failed\n");
+ StallControlPipe(bEPStat);
+ return;
+ }
+ // send status to host
+ DataIn();
+ }
+ }
+ else {
+ // absorb zero-length status message
+ iChunk = USBHwEPRead(0x00, NULL, 0);
+ DBG(iChunk > 0 ? "?" : "");
+ }
+ }
+ }
+ else if (bEP == 0x80) {
+ // IN transfer
+ // send more data if available (possibly a 0-length packet)
+ DataIn();
+ }
+ else {
+ ASSERT(FALSE);
+ }
+}
+
+
+/**
+ Registers a callback for handling requests
+
+ @param [in] iType Type of request, e.g. REQTYPE_TYPE_STANDARD
+ @param [in] *pfnHandler Callback function pointer
+ @param [in] *pbDataStore Data storage area for this type of request
+ */
+void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, unsigned char *pbDataStore)
+{
+ ASSERT(iType >= 0);
+ ASSERT(iType < 4);
+ apfnReqHandlers[iType] = pfnHandler;
+ apbDataStore[iType] = pbDataStore;
+}
+
--- /dev/null
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// CodeRed - comment out this printf, as will use real one from stdio.h
+// to implement output via semihosting
+
+//int printf(const char *format, ...);
+# include <stdio.h>
+
+#ifdef _DEBUG
+#define DBG printf
+#define ASSERT(x) if(!(x)){DBG("\nAssertion '%s' failed in %s:%s#%d!\n",#x,__FILE__,__FUNCTION__,__LINE__);while(1);}
+#else
+#define DBG(x ...)
+#define ASSERT(x)
+#endif
+
--- /dev/null
+/*\r
+ LPCUSB, an USB device driver for LPC microcontrollers\r
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)\r
+\r
+ Redistribution and use in source and binary forms, with or without\r
+ modification, are permitted provided that the following conditions are met:\r
+\r
+ 1. Redistributions of source code must retain the above copyright\r
+ notice, this list of conditions and the following disclaimer.\r
+ 2. Redistributions in binary form must reproduce the above copyright\r
+ notice, this list of conditions and the following disclaimer in the\r
+ documentation and/or other materials provided with the distribution.\r
+ 3. The name of the author may not be used to endorse or promote products\r
+ derived from this software without specific prior written permission.\r
+\r
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*/\r
+\r
+\r
+/** @file\r
+ USB hardware layer\r
+ */\r
+\r
+\r
+#include "usbdebug.h"\r
+#include "usbhw_lpc.h"\r
+#include "usbapi.h"\r
+\r
+/** Installed device interrupt handler */\r
+static TFnDevIntHandler *_pfnDevIntHandler = NULL;\r
+/** Installed endpoint interrupt handlers */\r
+static TFnEPIntHandler *_apfnEPIntHandlers[16];\r
+/** Installed frame interrupt handlers */\r
+static TFnFrameHandler *_pfnFrameHandler = NULL;\r
+\r
+/** convert from endpoint address to endpoint index */\r
+#define EP2IDX(bEP) ((((bEP)&0xF)<<1)|(((bEP)&0x80)>>7))\r
+/** convert from endpoint index to endpoint address */\r
+#define IDX2EP(idx) ((((idx)<<7)&0x80)|(((idx)>>1)&0xF))\r
+\r
+\r
+\r
+/**\r
+ Local function to wait for a device interrupt (and clear it)\r
+\r
+ @param [in] dwIntr Bitmask of interrupts to wait for\r
+ */\r
+static void Wait4DevInt(unsigned long dwIntr)\r
+{\r
+ // wait for specific interrupt\r
+ while ((USB->USBDevIntSt & dwIntr) != dwIntr);\r
+ // clear the interrupt bits\r
+ USB->USBDevIntClr = dwIntr;\r
+}\r
+\r
+\r
+/**\r
+ Local function to send a command to the USB protocol engine\r
+\r
+ @param [in] bCmd Command to send\r
+ */\r
+static void USBHwCmd(unsigned char bCmd)\r
+{\r
+ // clear CDFULL/CCEMTY\r
+ USB->USBDevIntClr = CDFULL | CCEMTY;\r
+ // write command code\r
+ USB->USBCmdCode = 0x00000500 | (bCmd << 16);\r
+ Wait4DevInt(CCEMTY);\r
+}\r
+\r
+\r
+/**\r
+ Local function to send a command + data to the USB protocol engine\r
+\r
+ @param [in] bCmd Command to send\r
+ @param [in] bData Data to send\r
+ */\r
+static void USBHwCmdWrite(unsigned char bCmd, unsigned short bData)\r
+{\r
+ // write command code\r
+ USBHwCmd(bCmd);\r
+\r
+ // write command data\r
+ USB->USBCmdCode = 0x00000100 | (bData << 16);\r
+ Wait4DevInt(CCEMTY);\r
+}\r
+\r
+\r
+/**\r
+ Local function to send a command to the USB protocol engine and read data\r
+\r
+ @param [in] bCmd Command to send\r
+\r
+ @return the data\r
+ */\r
+static unsigned char USBHwCmdRead(unsigned char bCmd)\r
+{\r
+ // write command code\r
+ USBHwCmd(bCmd);\r
+\r
+ // get data\r
+ USB->USBCmdCode = 0x00000200 | (bCmd << 16);\r
+ Wait4DevInt(CDFULL);\r
+ return USB->USBCmdData;\r
+}\r
+\r
+\r
+/**\r
+ 'Realizes' an endpoint, meaning that buffer space is reserved for\r
+ it. An endpoint needs to be realised before it can be used.\r
+\r
+ From experiments, it appears that a USB reset causes USBReEP to\r
+ re-initialise to 3 (= just the control endpoints).\r
+ However, a USB bus reset does not disturb the USBMaxPSize settings.\r
+\r
+ @param [in] idx Endpoint index\r
+ @param [in] wMaxPSize Maximum packet size for this endpoint\r
+ */\r
+static void USBHwEPRealize(int idx, unsigned short wMaxPSize)\r
+{\r
+ USB->USBReEP |= (1 << idx);\r
+ USB->USBEpInd = idx;\r
+ USB->USBMaxPSize = wMaxPSize;\r
+ Wait4DevInt(EP_RLZED);\r
+}\r
+\r
+\r
+/**\r
+ Enables or disables an endpoint\r
+\r
+ @param [in] idx Endpoint index\r
+ @param [in] fEnable TRUE to enable, FALSE to disable\r
+ */\r
+static void USBHwEPEnable(int idx, BOOL fEnable)\r
+{\r
+ USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fEnable ? 0 : EP_DA);\r
+}\r
+\r
+\r
+/**\r
+ Configures an endpoint and enables it\r
+\r
+ @param [in] bEP Endpoint number\r
+ @param [in] wMaxPacketSize Maximum packet size for this EP\r
+ */\r
+void USBHwEPConfig(unsigned char bEP, unsigned short wMaxPacketSize)\r
+{\r
+ int idx;\r
+\r
+ idx = EP2IDX(bEP);\r
+\r
+ // realise EP\r
+ USBHwEPRealize(idx, wMaxPacketSize);\r
+\r
+ // enable EP\r
+ USBHwEPEnable(idx, TRUE);\r
+}\r
+\r
+\r
+/**\r
+ Registers an endpoint event callback\r
+\r
+ @param [in] bEP Endpoint number\r
+ @param [in] pfnHandler Callback function\r
+ */\r
+void USBHwRegisterEPIntHandler(unsigned char bEP, TFnEPIntHandler *pfnHandler)\r
+{\r
+ int idx;\r
+\r
+ idx = EP2IDX(bEP);\r
+\r
+ ASSERT(idx<32);\r
+\r
+ /* add handler to list of EP handlers */\r
+ _apfnEPIntHandlers[idx / 2] = pfnHandler;\r
+\r
+ /* enable EP interrupt */\r
+ USB->USBEpIntEn |= (1 << idx);\r
+ USB->USBDevIntEn |= EP_SLOW;\r
+\r
+ DBG("Registered handler for EP 0x%x\n", bEP);\r
+}\r
+\r
+\r
+/**\r
+ Registers an device status callback\r
+\r
+ @param [in] pfnHandler Callback function\r
+ */\r
+void USBHwRegisterDevIntHandler(TFnDevIntHandler *pfnHandler)\r
+{\r
+ _pfnDevIntHandler = pfnHandler;\r
+\r
+ // enable device interrupt\r
+ USB->USBDevIntEn |= DEV_STAT;\r
+\r
+ DBG("Registered handler for device status\n");\r
+}\r
+\r
+\r
+/**\r
+ Registers the frame callback\r
+\r
+ @param [in] pfnHandler Callback function\r
+ */\r
+void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler)\r
+{\r
+ _pfnFrameHandler = pfnHandler;\r
+\r
+ // enable device interrupt\r
+ USB->USBDevIntEn |= FRAME;\r
+\r
+ DBG("Registered handler for frame\n");\r
+}\r
+\r
+\r
+/**\r
+ Sets the USB address.\r
+\r
+ @param [in] bAddr Device address to set\r
+ */\r
+void USBHwSetAddress(unsigned char bAddr)\r
+{\r
+ USBHwCmdWrite(CMD_DEV_SET_ADDRESS, DEV_EN | bAddr);\r
+}\r
+\r
+\r
+/**\r
+ Connects or disconnects from the USB bus\r
+\r
+ @param [in] fConnect If TRUE, connect, otherwise disconnect\r
+ */\r
+void USBHwConnect(BOOL fConnect)\r
+{\r
+ USBHwCmdWrite(CMD_DEV_STATUS, fConnect ? CON : 0);\r
+}\r
+\r
+\r
+/**\r
+ Enables interrupt on NAK condition\r
+\r
+ For IN endpoints a NAK is generated when the host wants to read data\r
+ from the device, but none is available in the endpoint buffer.\r
+ For OUT endpoints a NAK is generated when the host wants to write data\r
+ to the device, but the endpoint buffer is still full.\r
+\r
+ The endpoint interrupt handlers can distinguish regular (ACK) interrupts\r
+ from NAK interrupt by checking the bits in their bEPStatus argument.\r
+\r
+ @param [in] bIntBits Bitmap indicating which NAK interrupts to enable\r
+ */\r
+void USBHwNakIntEnable(unsigned char bIntBits)\r
+{\r
+ USBHwCmdWrite(CMD_DEV_SET_MODE, bIntBits);\r
+}\r
+\r
+\r
+/**\r
+ Gets the status from a specific endpoint.\r
+\r
+ @param [in] bEP Endpoint number\r
+ @return Endpoint status byte (containing EP_STATUS_xxx bits)\r
+ */\r
+unsigned char USBHwEPGetStatus(unsigned char bEP)\r
+{\r
+ int idx = EP2IDX(bEP);\r
+\r
+ return USBHwCmdRead(CMD_EP_SELECT | idx);\r
+}\r
+\r
+\r
+/**\r
+ Sets the stalled property of an endpoint\r
+\r
+ @param [in] bEP Endpoint number\r
+ @param [in] fStall TRUE to stall, FALSE to unstall\r
+ */\r
+void USBHwEPStall(unsigned char bEP, BOOL fStall)\r
+{\r
+ int idx = EP2IDX(bEP);\r
+\r
+ USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fStall ? EP_ST : 0);\r
+}\r
+\r
+\r
+/**\r
+ Writes data to an endpoint buffer\r
+\r
+ @param [in] bEP Endpoint number\r
+ @param [in] pbBuf Endpoint data\r
+ @param [in] iLen Number of bytes to write\r
+\r
+ @return TRUE if the data was successfully written or <0 in case of error.\r
+*/\r
+int USBHwEPWrite(unsigned char bEP, unsigned char *pbBuf, int iLen)\r
+{\r
+ int idx;\r
+\r
+ idx = EP2IDX(bEP);\r
+\r
+ // set write enable for specific endpoint\r
+ USB->USBCtrl = WR_EN | ((bEP & 0xF) << 2);\r
+\r
+ // set packet length\r
+ USB->USBTxPLen = iLen;\r
+\r
+ // write data\r
+ while (USB->USBCtrl & WR_EN) {\r
+ USB->USBTxData = (pbBuf[3] << 24) | (pbBuf[2] << 16) | (pbBuf[1] << 8) | pbBuf[0];\r
+ pbBuf += 4;\r
+ }\r
+\r
+ // select endpoint and validate buffer\r
+ USBHwCmd(CMD_EP_SELECT | idx);\r
+ USBHwCmd(CMD_EP_VALIDATE_BUFFER);\r
+\r
+ return iLen;\r
+}\r
+\r
+\r
+/**\r
+ Reads data from an endpoint buffer\r
+\r
+ @param [in] bEP Endpoint number\r
+ @param [in] pbBuf Endpoint data\r
+ @param [in] iMaxLen Maximum number of bytes to read\r
+\r
+ @return the number of bytes available in the EP (possibly more than iMaxLen),\r
+ or <0 in case of error.\r
+ */\r
+int USBHwEPRead(unsigned char bEP, unsigned char *pbBuf, int iMaxLen)\r
+{\r
+ unsigned int i, idx;\r
+ unsigned long dwData, dwLen;\r
+\r
+ idx = EP2IDX(bEP);\r
+\r
+ // set read enable bit for specific endpoint\r
+ USB->USBCtrl = RD_EN | ((bEP & 0xF) << 2);\r
+\r
+ // wait for PKT_RDY\r
+ do {\r
+ dwLen = USB->USBRxPLen;\r
+ } while ((dwLen & PKT_RDY) == 0);\r
+\r
+ // packet valid?\r
+ if ((dwLen & DV) == 0) {\r
+ return -1;\r
+ }\r
+\r
+ // get length\r
+ dwLen &= PKT_LNGTH_MASK;\r
+\r
+ // get data\r
+ dwData = 0;\r
+ for (i = 0; i < dwLen; i++) {\r
+ if ((i % 4) == 0) {\r
+ dwData = USB->USBRxData;\r
+ }\r
+ if ((pbBuf != NULL) && ((int)i < iMaxLen)) {\r
+ pbBuf[i] = dwData & 0xFF;\r
+ }\r
+ dwData >>= 8;\r
+ }\r
+\r
+ // make sure RD_EN is clear\r
+ USB->USBCtrl = 0;\r
+\r
+ // select endpoint and clear buffer\r
+ USBHwCmd(CMD_EP_SELECT | idx);\r
+ USBHwCmd(CMD_EP_CLEAR_BUFFER);\r
+\r
+ return dwLen;\r
+}\r
+\r
+\r
+/**\r
+ Sets the 'configured' state.\r
+\r
+ All registered endpoints are 'realised' and enabled, and the\r
+ 'configured' bit is set in the device status register.\r
+\r
+ @param [in] fConfigured If TRUE, configure device, else unconfigure\r
+ */\r
+void USBHwConfigDevice(BOOL fConfigured)\r
+{\r
+ // set configured bit\r
+ USBHwCmdWrite(CMD_DEV_CONFIG, fConfigured ? CONF_DEVICE : 0);\r
+}\r
+\r
+\r
+/**\r
+ USB interrupt handler\r
+\r
+ @todo Get all 11 bits of frame number instead of just 8\r
+\r
+ Endpoint interrupts are mapped to the slow interrupt\r
+ */\r
+void USBHwISR(void)\r
+{\r
+ unsigned long dwStatus;\r
+ unsigned long dwIntBit;\r
+ unsigned char bEPStat, bDevStat, bStat;\r
+ int i;\r
+ unsigned short wFrame;\r
+\r
+ // handle device interrupts\r
+ dwStatus = USB->USBDevIntSt;\r
+\r
+ // frame interrupt\r
+ if (dwStatus & FRAME) {\r
+ // clear int\r
+ USB->USBDevIntClr = FRAME;\r
+ // call handler\r
+ if (_pfnFrameHandler != NULL) {\r
+ wFrame = USBHwCmdRead(CMD_DEV_READ_CUR_FRAME_NR);\r
+ _pfnFrameHandler(wFrame);\r
+ }\r
+ }\r
+\r
+ // device status interrupt\r
+ if (dwStatus & DEV_STAT) {\r
+ /* Clear DEV_STAT interrupt before reading DEV_STAT register.\r
+ This prevents corrupted device status reads, see\r
+ LPC2148 User manual revision 2, 25 july 2006.\r
+ */\r
+ USB->USBDevIntClr = DEV_STAT;\r
+ bDevStat = USBHwCmdRead(CMD_DEV_STATUS);\r
+ if (bDevStat & (CON_CH | SUS_CH | RST)) {\r
+ // convert device status into something HW independent\r
+ bStat = ((bDevStat & CON) ? DEV_STATUS_CONNECT : 0) |\r
+ ((bDevStat & SUS) ? DEV_STATUS_SUSPEND : 0) |\r
+ ((bDevStat & RST) ? DEV_STATUS_RESET : 0);\r
+ // call handler\r
+ if (_pfnDevIntHandler != NULL) {\r
+ _pfnDevIntHandler(bStat);\r
+ }\r
+ }\r
+ }\r
+\r
+ // endpoint interrupt\r
+ if (dwStatus & EP_SLOW) {\r
+ // clear EP_SLOW\r
+ USB->USBDevIntClr = EP_SLOW;\r
+ // check all endpoints\r
+ for (i = 0; i < 32; i++) {\r
+ dwIntBit = (1 << i);\r
+ if (USB->USBEpIntSt & dwIntBit) {\r
+ // clear int (and retrieve status)\r
+ USB->USBEpIntClr = dwIntBit;\r
+ Wait4DevInt(CDFULL);\r
+ bEPStat = USB->USBCmdData;\r
+ // convert EP pipe stat into something HW independent\r
+ bStat = ((bEPStat & EPSTAT_FE) ? EP_STATUS_DATA : 0) |\r
+ ((bEPStat & EPSTAT_ST) ? EP_STATUS_STALLED : 0) |\r
+ ((bEPStat & EPSTAT_STP) ? EP_STATUS_SETUP : 0) |\r
+ ((bEPStat & EPSTAT_EPN) ? EP_STATUS_NACKED : 0) |\r
+ ((bEPStat & EPSTAT_PO) ? EP_STATUS_ERROR : 0);\r
+ // call handler\r
+ if (_apfnEPIntHandlers[i / 2] != NULL) {\r
+ _apfnEPIntHandlers[i / 2](IDX2EP(i), bStat);\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
+/**\r
+ Initialises the USB hardware\r
+\r
+\r
+ @return TRUE if the hardware was successfully initialised\r
+ */\r
+BOOL USBHwInit(void)\r
+{\r
+ // P2.9 -> USB_CONNECT\r
+ PINCON->PINSEL4 &= ~0x000C0000;\r
+ PINCON->PINSEL4 |= 0x00040000;\r
+\r
+ // P1.18 -> USB_UP_LED\r
+ // P1.30 -> VBUS\r
+ PINCON->PINSEL3 &= ~0x30000030;\r
+ PINCON->PINSEL3 |= 0x20000010;\r
+\r
+ // P0.29 -> USB_D+\r
+ // P0.30 -> USB_D-\r
+ PINCON->PINSEL1 &= ~0x3C000000;\r
+ PINCON->PINSEL1 |= 0x14000000;\r
+\r
+ // enable PUSB\r
+ SC->PCONP |= (1 << 31);\r
+\r
+ USB->OTGClkCtrl = 0x12; /* Dev clock, AHB clock enable */\r
+ while ((USB->OTGClkSt & 0x12) != 0x12);\r
+\r
+ // disable/clear all interrupts for now\r
+ USB->USBDevIntEn = 0;\r
+ USB->USBDevIntClr = 0xFFFFFFFF;\r
+ USB->USBDevIntPri = 0;\r
+\r
+ USB->USBEpIntEn = 0;\r
+ USB->USBEpIntClr = 0xFFFFFFFF;\r
+ USB->USBEpIntPri = 0;\r
+\r
+ // by default, only ACKs generate interrupts\r
+ USBHwNakIntEnable(0);\r
+\r
+ return TRUE;\r
+}\r
+\r
--- /dev/null
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/**
+ Hardware definitions for the LPC176x USB controller
+
+ These are private to the usbhw module
+*/
+
+// CodeRed - pull in defines from NXP header file
+//#include "NXP\LPC17xx\LPC17xx.h"
+#include "LPC17xx.h"
+
+
+// CodeRed - these registers have been renamed on LPC176x
+#define USBReEP USBReEp
+#define OTG_CLK_CTRL USBClkCtrl
+#define OTG_CLK_STAT USBClkSt
+
+/* USBIntSt bits */
+#define USB_INT_REQ_LP (1<<0)
+#define USB_INT_REQ_HP (1<<1)
+#define USB_INT_REQ_DMA (1<<2)
+#define USB_need_clock (1<<8)
+#define EN_USB_BITS (1<<31)
+
+/* USBDevInt... bits */
+#define FRAME (1<<0)
+#define EP_FAST (1<<1)
+#define EP_SLOW (1<<2)
+#define DEV_STAT (1<<3)
+#define CCEMTY (1<<4)
+#define CDFULL (1<<5)
+#define RxENDPKT (1<<6)
+#define TxENDPKT (1<<7)
+#define EP_RLZED (1<<8)
+#define ERR_INT (1<<9)
+
+/* USBRxPLen bits */
+#define PKT_LNGTH (1<<0)
+#define PKT_LNGTH_MASK 0x3FF
+#define DV (1<<10)
+#define PKT_RDY (1<<11)
+
+/* USBCtrl bits */
+#define RD_EN (1<<0)
+#define WR_EN (1<<1)
+#define LOG_ENDPOINT (1<<2)
+
+/* protocol engine command codes */
+ /* device commands */
+#define CMD_DEV_SET_ADDRESS 0xD0
+#define CMD_DEV_CONFIG 0xD8
+#define CMD_DEV_SET_MODE 0xF3
+#define CMD_DEV_READ_CUR_FRAME_NR 0xF5
+#define CMD_DEV_READ_TEST_REG 0xFD
+#define CMD_DEV_STATUS 0xFE /* read/write */
+#define CMD_DEV_GET_ERROR_CODE 0xFF
+#define CMD_DEV_READ_ERROR_STATUS 0xFB
+ /* endpoint commands */
+#define CMD_EP_SELECT 0x00
+#define CMD_EP_SELECT_CLEAR 0x40
+#define CMD_EP_SET_STATUS 0x40
+#define CMD_EP_CLEAR_BUFFER 0xF2
+#define CMD_EP_VALIDATE_BUFFER 0xFA
+
+/* set address command */
+#define DEV_ADDR (1<<0)
+#define DEV_EN (1<<7)
+
+/* configure device command */
+#define CONF_DEVICE (1<<0)
+
+/* set mode command */
+#define AP_CLK (1<<0)
+#define INAK_CI (1<<1)
+#define INAK_CO (1<<2)
+#define INAK_II (1<<3)
+#define INAK_IO (1<<4)
+#define INAK_BI (1<<5)
+#define INAK_BO (1<<6)
+
+/* set get device status command */
+#define CON (1<<0)
+#define CON_CH (1<<1)
+#define SUS (1<<2)
+#define SUS_CH (1<<3)
+#define RST (1<<4)
+
+/* get error code command */
+// ...
+
+/* Select Endpoint command read bits */
+#define EPSTAT_FE (1<<0)
+#define EPSTAT_ST (1<<1)
+#define EPSTAT_STP (1<<2)
+#define EPSTAT_PO (1<<3)
+#define EPSTAT_EPN (1<<4)
+#define EPSTAT_B1FULL (1<<5)
+#define EPSTAT_B2FULL (1<<6)
+
+/* CMD_EP_SET_STATUS command */
+#define EP_ST (1<<0)
+#define EP_DA (1<<5)
+#define EP_RF_MO (1<<6)
+#define EP_CND_ST (1<<7)
+
+/* read error status command */
+#define PID_ERR (1<<0)
+#define UEPKT (1<<1)
+#define DCRC (1<<2)
+#define TIMEOUT (1<<3)
+#define EOP (1<<4)
+#define B_OVRN (1<<5)
+#define BTSTF (1<<6)
+#define TGL_ERR (1<<7)
+
+
+
+
+
+
+
+
--- /dev/null
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/** @file
+ USB stack initialisation
+ */
+
+
+#include "usbdebug.h"
+#include "usbapi.h"
+
+
+/** data storage area for standard requests */
+static unsigned char abStdReqData[8];
+
+
+/**
+ USB reset handler
+
+ @param [in] bDevStatus Device status
+ */
+static void HandleUsbReset(unsigned char bDevStatus)
+{
+ if (bDevStatus & DEV_STATUS_RESET) {
+ DBG("\n!");
+ }
+}
+
+
+/**
+ Initialises the USB hardware and sets up the USB stack by
+ installing default callbacks.
+
+ @return TRUE if initialisation was successful
+ */
+BOOL USBInit(void)
+{
+ // init hardware
+ USBHwInit();
+
+ // register bus reset handler
+ USBHwRegisterDevIntHandler(HandleUsbReset);
+
+ // register control transfer handler on EP0
+ USBHwRegisterEPIntHandler(0x00, USBHandleControlTransfer);
+ USBHwRegisterEPIntHandler(0x80, USBHandleControlTransfer);
+
+ // setup control endpoints
+ USBHwEPConfig(0x00, MAX_PACKET_SIZE0);
+ USBHwEPConfig(0x80, MAX_PACKET_SIZE0);
+
+ // register standard request handler
+ USBRegisterRequestHandler(REQTYPE_TYPE_STANDARD, USBHandleStandardRequest, abStdReqData);
+
+ return TRUE;
+}
+
--- /dev/null
+/*\r
+ LPCUSB, an USB device driver for LPC microcontrollers\r
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)\r
+\r
+ Redistribution and use in source and binary forms, with or without\r
+ modification, are permitted provided that the following conditions are met:\r
+\r
+ 1. Redistributions of source code must retain the above copyright\r
+ notice, this list of conditions and the following disclaimer.\r
+ 2. Redistributions in binary form must reproduce the above copyright\r
+ notice, this list of conditions and the following disclaimer in the\r
+ documentation and/or other materials provided with the distribution.\r
+ 3. The name of the author may not be used to endorse or promote products\r
+ derived from this software without specific prior written permission.\r
+\r
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*/\r
+\r
+\r
+/** @file\r
+ Standard request handler.\r
+\r
+ This modules handles the 'chapter 9' processing, specifically the\r
+ standard device requests in table 9-3 from the universal serial bus\r
+ specification revision 2.0\r
+\r
+ Specific types of devices may specify additional requests (for example\r
+ HID devices add a GET_DESCRIPTOR request for interfaces), but they\r
+ will not be part of this module.\r
+\r
+ @todo some requests have to return a request error if device not configured:\r
+ @todo GET_INTERFACE, GET_STATUS, SET_INTERFACE, SYNCH_FRAME\r
+ @todo this applies to the following if endpoint != 0:\r
+ @todo SET_FEATURE, GET_FEATURE\r
+*/\r
+\r
+#include "usbdebug.h"\r
+#include "usbstruct.h"\r
+#include "usbapi.h"\r
+\r
+#define MAX_DESC_HANDLERS 4 /**< device, interface, endpoint, other */\r
+\r
+\r
+/* general descriptor field offsets */\r
+#define DESC_bLength 0 /**< length offset */\r
+#define DESC_bDescriptorType 1 /**< descriptor type offset */\r
+\r
+/* config descriptor field offsets */\r
+#define CONF_DESC_wTotalLength 2 /**< total length offset */\r
+#define CONF_DESC_bConfigurationValue 5 /**< configuration value offset */\r
+#define CONF_DESC_bmAttributes 7 /**< configuration characteristics */\r
+\r
+/* interface descriptor field offsets */\r
+#define INTF_DESC_bAlternateSetting 3 /**< alternate setting offset */\r
+\r
+/* endpoint descriptor field offsets */\r
+#define ENDP_DESC_bEndpointAddress 2 /**< endpoint address offset */\r
+#define ENDP_DESC_wMaxPacketSize 4 /**< maximum packet size offset */\r
+\r
+\r
+/** Currently selected configuration */\r
+static unsigned char bConfiguration = 0;\r
+/** Installed custom request handler */\r
+static TFnHandleRequest *pfnHandleCustomReq = NULL;\r
+/** Pointer to registered descriptors */\r
+static const unsigned char *pabDescrip = NULL;\r
+\r
+\r
+/**\r
+ Registers a pointer to a descriptor block containing all descriptors\r
+ for the device.\r
+\r
+ @param [in] pabDescriptors The descriptor byte array\r
+ */\r
+void USBRegisterDescriptors(const unsigned char *pabDescriptors)\r
+{\r
+ pabDescrip = pabDescriptors;\r
+}\r
+\r
+\r
+/**\r
+ Parses the list of installed USB descriptors and attempts to find\r
+ the specified USB descriptor.\r
+\r
+ @param [in] wTypeIndex Type and index of the descriptor\r
+ @param [in] wLangID Language ID of the descriptor (currently unused)\r
+ @param [out] *piLen Descriptor length\r
+ @param [out] *ppbData Descriptor data\r
+\r
+ @return TRUE if the descriptor was found, FALSE otherwise\r
+ */\r
+BOOL USBGetDescriptor(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData)\r
+{\r
+ unsigned char bType, bIndex;\r
+ unsigned char *pab;\r
+ int iCurIndex;\r
+\r
+ ( void ) wLangID;\r
+ ASSERT(pabDescrip != NULL);\r
+\r
+ bType = GET_DESC_TYPE(wTypeIndex);\r
+ bIndex = GET_DESC_INDEX(wTypeIndex);\r
+\r
+ pab = (unsigned char *)pabDescrip;\r
+ iCurIndex = 0;\r
+\r
+ while (pab[DESC_bLength] != 0) {\r
+ if (pab[DESC_bDescriptorType] == bType) {\r
+ if (iCurIndex == bIndex) {\r
+ // set data pointer\r
+ *ppbData = pab;\r
+ // get length from structure\r
+ if (bType == DESC_CONFIGURATION) {\r
+ // configuration descriptor is an exception, length is at offset 2 and 3\r
+ *piLen = (pab[CONF_DESC_wTotalLength]) |\r
+ (pab[CONF_DESC_wTotalLength + 1] << 8);\r
+ }\r
+ else {\r
+ // normally length is at offset 0\r
+ *piLen = pab[DESC_bLength];\r
+ }\r
+ return TRUE;\r
+ }\r
+ iCurIndex++;\r
+ }\r
+ // skip to next descriptor\r
+ pab += pab[DESC_bLength];\r
+ }\r
+ // nothing found\r
+ DBG("Desc %x not found!\n", wTypeIndex);\r
+ return FALSE;\r
+}\r
+\r
+\r
+/**\r
+ Configures the device according to the specified configuration index and\r
+ alternate setting by parsing the installed USB descriptor list.\r
+ A configuration index of 0 unconfigures the device.\r
+\r
+ @param [in] bConfigIndex Configuration index\r
+ @param [in] bAltSetting Alternate setting number\r
+\r
+ @todo function always returns TRUE, add stricter checking?\r
+\r
+ @return TRUE if successfully configured, FALSE otherwise\r
+ */\r
+static BOOL USBSetConfiguration(unsigned char bConfigIndex, unsigned char bAltSetting)\r
+{\r
+ unsigned char *pab;\r
+ unsigned char bCurConfig, bCurAltSetting;\r
+ unsigned char bEP;\r
+ unsigned short wMaxPktSize;\r
+\r
+ ASSERT(pabDescrip != NULL);\r
+\r
+ if (bConfigIndex == 0) {\r
+ // unconfigure device\r
+ USBHwConfigDevice(FALSE);\r
+ }\r
+ else {\r
+ // configure endpoints for this configuration/altsetting\r
+ pab = (unsigned char *)pabDescrip;\r
+ bCurConfig = 0xFF;\r
+ bCurAltSetting = 0xFF;\r
+\r
+ while (pab[DESC_bLength] != 0) {\r
+\r
+ switch (pab[DESC_bDescriptorType]) {\r
+\r
+ case DESC_CONFIGURATION:\r
+ // remember current configuration index\r
+ bCurConfig = pab[CONF_DESC_bConfigurationValue];\r
+ break;\r
+\r
+ case DESC_INTERFACE:\r
+ // remember current alternate setting\r
+ bCurAltSetting = pab[INTF_DESC_bAlternateSetting];\r
+ break;\r
+\r
+ case DESC_ENDPOINT:\r
+ if ((bCurConfig == bConfigIndex) &&\r
+ (bCurAltSetting == bAltSetting)) {\r
+ // endpoint found for desired config and alternate setting\r
+ bEP = pab[ENDP_DESC_bEndpointAddress];\r
+ wMaxPktSize = (pab[ENDP_DESC_wMaxPacketSize]) |\r
+ (pab[ENDP_DESC_wMaxPacketSize + 1] << 8);\r
+ // configure endpoint\r
+ USBHwEPConfig(bEP, wMaxPktSize);\r
+ }\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ // skip to next descriptor\r
+ pab += pab[DESC_bLength];\r
+ }\r
+\r
+ // configure device\r
+ USBHwConfigDevice(TRUE);\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+\r
+/**\r
+ Local function to handle a standard device request\r
+\r
+ @param [in] pSetup The setup packet\r
+ @param [in,out] *piLen Pointer to data length\r
+ @param [in,out] ppbData Data buffer.\r
+\r
+ @return TRUE if the request was handled successfully\r
+ */\r
+static BOOL HandleStdDeviceReq(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)\r
+{\r
+ unsigned char *pbData = *ppbData;\r
+\r
+ switch (pSetup->bRequest) {\r
+\r
+ case REQ_GET_STATUS:\r
+ // bit 0: self-powered\r
+ // bit 1: remote wakeup = not supported\r
+ pbData[0] = 0;\r
+ pbData[1] = 0;\r
+ *piLen = 2;\r
+ break;\r
+\r
+ case REQ_SET_ADDRESS:\r
+ USBHwSetAddress(pSetup->wValue);\r
+ break;\r
+\r
+ case REQ_GET_DESCRIPTOR:\r
+ DBG("D%x", pSetup->wValue);\r
+ return USBGetDescriptor(pSetup->wValue, pSetup->wIndex, piLen, ppbData);\r
+\r
+ case REQ_GET_CONFIGURATION:\r
+ // indicate if we are configured\r
+ pbData[0] = bConfiguration;\r
+ *piLen = 1;\r
+ break;\r
+\r
+ case REQ_SET_CONFIGURATION:\r
+ if (!USBSetConfiguration(pSetup->wValue & 0xFF, 0)) {\r
+ DBG("USBSetConfiguration failed!\n");\r
+ return FALSE;\r
+ }\r
+ // configuration successful, update current configuration\r
+ bConfiguration = pSetup->wValue & 0xFF;\r
+ break;\r
+\r
+ case REQ_CLEAR_FEATURE:\r
+ case REQ_SET_FEATURE:\r
+ if (pSetup->wValue == FEA_REMOTE_WAKEUP) {\r
+ // put DEVICE_REMOTE_WAKEUP code here\r
+ }\r
+ if (pSetup->wValue == FEA_TEST_MODE) {\r
+ // put TEST_MODE code here\r
+ }\r
+ return FALSE;\r
+\r
+ case REQ_SET_DESCRIPTOR:\r
+ DBG("Device req %d not implemented\n", pSetup->bRequest);\r
+ return FALSE;\r
+\r
+ default:\r
+ DBG("Illegal device req %d\n", pSetup->bRequest);\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+\r
+/**\r
+ Local function to handle a standard interface request\r
+\r
+ @param [in] pSetup The setup packet\r
+ @param [in,out] *piLen Pointer to data length\r
+ @param [in] ppbData Data buffer.\r
+\r
+ @return TRUE if the request was handled successfully\r
+ */\r
+static BOOL HandleStdInterfaceReq(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)\r
+{\r
+ unsigned char *pbData = *ppbData;\r
+\r
+ switch (pSetup->bRequest) {\r
+\r
+ case REQ_GET_STATUS:\r
+ // no bits specified\r
+ pbData[0] = 0;\r
+ pbData[1] = 0;\r
+ *piLen = 2;\r
+ break;\r
+\r
+ case REQ_CLEAR_FEATURE:\r
+ case REQ_SET_FEATURE:\r
+ // not defined for interface\r
+ return FALSE;\r
+\r
+ case REQ_GET_INTERFACE: // TODO use bNumInterfaces\r
+ // there is only one interface, return n-1 (= 0)\r
+ pbData[0] = 0;\r
+ *piLen = 1;\r
+ break;\r
+\r
+ case REQ_SET_INTERFACE: // TODO use bNumInterfaces\r
+ // there is only one interface (= 0)\r
+ if (pSetup->wValue != 0) {\r
+ return FALSE;\r
+ }\r
+ *piLen = 0;\r
+ break;\r
+\r
+ default:\r
+ DBG("Illegal interface req %d\n", pSetup->bRequest);\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+\r
+/**\r
+ Local function to handle a standard endpoint request\r
+\r
+ @param [in] pSetup The setup packet\r
+ @param [in,out] *piLen Pointer to data length\r
+ @param [in] ppbData Data buffer.\r
+\r
+ @return TRUE if the request was handled successfully\r
+ */\r
+static BOOL HandleStdEndPointReq(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)\r
+{\r
+ unsigned char *pbData = *ppbData;\r
+\r
+ switch (pSetup->bRequest) {\r
+ case REQ_GET_STATUS:\r
+ // bit 0 = endpointed halted or not\r
+ pbData[0] = (USBHwEPGetStatus(pSetup->wIndex) & EP_STATUS_STALLED) ? 1 : 0;\r
+ pbData[1] = 0;\r
+ *piLen = 2;\r
+ break;\r
+\r
+ case REQ_CLEAR_FEATURE:\r
+ if (pSetup->wValue == FEA_ENDPOINT_HALT) {\r
+ // clear HALT by unstalling\r
+ USBHwEPStall(pSetup->wIndex, FALSE);\r
+ break;\r
+ }\r
+ // only ENDPOINT_HALT defined for endpoints\r
+ return FALSE;\r
+\r
+ case REQ_SET_FEATURE:\r
+ if (pSetup->wValue == FEA_ENDPOINT_HALT) {\r
+ // set HALT by stalling\r
+ USBHwEPStall(pSetup->wIndex, TRUE);\r
+ break;\r
+ }\r
+ // only ENDPOINT_HALT defined for endpoints\r
+ return FALSE;\r
+\r
+ case REQ_SYNCH_FRAME:\r
+ DBG("EP req %d not implemented\n", pSetup->bRequest);\r
+ return FALSE;\r
+\r
+ default:\r
+ DBG("Illegal EP req %d\n", pSetup->bRequest);\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+\r
+/**\r
+ Default handler for standard ('chapter 9') requests\r
+\r
+ If a custom request handler was installed, this handler is called first.\r
+\r
+ @param [in] pSetup The setup packet\r
+ @param [in,out] *piLen Pointer to data length\r
+ @param [in] ppbData Data buffer.\r
+\r
+ @return TRUE if the request was handled successfully\r
+ */\r
+BOOL USBHandleStandardRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)\r
+{\r
+ // try the custom request handler first\r
+ if ((pfnHandleCustomReq != NULL) && pfnHandleCustomReq(pSetup, piLen, ppbData)) {\r
+ return TRUE;\r
+ }\r
+\r
+ switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) {\r
+ case REQTYPE_RECIP_DEVICE: return HandleStdDeviceReq(pSetup, piLen, ppbData);\r
+ case REQTYPE_RECIP_INTERFACE: return HandleStdInterfaceReq(pSetup, piLen, ppbData);\r
+ case REQTYPE_RECIP_ENDPOINT: return HandleStdEndPointReq(pSetup, piLen, ppbData);\r
+ default: return FALSE;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ Registers a callback for custom device requests\r
+\r
+ In USBHandleStandardRequest, the custom request handler gets a first\r
+ chance at handling the request before it is handed over to the 'chapter 9'\r
+ request handler.\r
+\r
+ This can be used for example in HID devices, where a REQ_GET_DESCRIPTOR\r
+ request is sent to an interface, which is not covered by the 'chapter 9'\r
+ specification.\r
+\r
+ @param [in] pfnHandler Callback function pointer\r
+ */\r
+void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler)\r
+{\r
+ pfnHandleCustomReq = pfnHandler;\r
+}\r
+\r
--- /dev/null
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/**
+ Definitions of structures of standard USB packets
+*/
+
+#ifndef _USBSTRUCT_H_
+#define _USBSTRUCT_H_
+
+// CodeRed - include the LPCUSB type.h file rather than NXP one directly
+#include "type.h"
+
+/** setup packet definitions */
+typedef struct {
+ unsigned char bmRequestType; /**< characteristics of the specific request */
+ unsigned char bRequest; /**< specific request */
+ unsigned short wValue; /**< request specific parameter */
+ unsigned short wIndex; /**< request specific parameter */
+ unsigned short wLength; /**< length of data transfered in data phase */
+} TSetupPacket;
+
+
+#define REQTYPE_GET_DIR(x) (((x)>>7)&0x01)
+#define REQTYPE_GET_TYPE(x) (((x)>>5)&0x03)
+#define REQTYPE_GET_RECIP(x) ((x)&0x1F)
+
+#define REQTYPE_DIR_TO_DEVICE 0
+#define REQTYPE_DIR_TO_HOST 1
+
+#define REQTYPE_TYPE_STANDARD 0
+#define REQTYPE_TYPE_CLASS 1
+#define REQTYPE_TYPE_VENDOR 2
+#define REQTYPE_TYPE_RESERVED 3
+
+#define REQTYPE_RECIP_DEVICE 0
+#define REQTYPE_RECIP_INTERFACE 1
+#define REQTYPE_RECIP_ENDPOINT 2
+#define REQTYPE_RECIP_OTHER 3
+
+/* standard requests */
+#define REQ_GET_STATUS 0x00
+#define REQ_CLEAR_FEATURE 0x01
+#define REQ_SET_FEATURE 0x03
+#define REQ_SET_ADDRESS 0x05
+#define REQ_GET_DESCRIPTOR 0x06
+#define REQ_SET_DESCRIPTOR 0x07
+#define REQ_GET_CONFIGURATION 0x08
+#define REQ_SET_CONFIGURATION 0x09
+#define REQ_GET_INTERFACE 0x0A
+#define REQ_SET_INTERFACE 0x0B
+#define REQ_SYNCH_FRAME 0x0C
+
+/* class requests HID */
+#define HID_GET_REPORT 0x01
+#define HID_GET_IDLE 0x02
+#define HID_GET_PROTOCOL 0x03
+#define HID_SET_REPORT 0x09
+#define HID_SET_IDLE 0x0A
+#define HID_SET_PROTOCOL 0x0B
+
+/* feature selectors */
+#define FEA_ENDPOINT_HALT 0x00
+#define FEA_REMOTE_WAKEUP 0x01
+#define FEA_TEST_MODE 0x02
+
+/*
+ USB descriptors
+*/
+
+/** USB descriptor header */
+typedef struct {
+ unsigned char bLength; /**< descriptor length */
+ unsigned char bDescriptorType; /**< descriptor type */
+} TUSBDescHeader;
+
+#define DESC_DEVICE 1
+#define DESC_CONFIGURATION 2
+#define DESC_STRING 3
+#define DESC_INTERFACE 4
+#define DESC_ENDPOINT 5
+#define DESC_DEVICE_QUALIFIER 6
+#define DESC_OTHER_SPEED 7
+#define DESC_INTERFACE_POWER 8
+
+#define DESC_HID_HID 0x21
+#define DESC_HID_REPORT 0x22
+#define DESC_HID_PHYSICAL 0x23
+
+#define GET_DESC_TYPE(x) (((x)>>8)&0xFF)
+#define GET_DESC_INDEX(x) ((x)&0xFF)
+
+#endif /* _USBSTRUCT_H_ */
+
--- /dev/null
+/*\r
+ FreeRTOS V6.0.2 - Copyright (C) 2010 Real Time Engineers Ltd.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * If you are: *\r
+ * *\r
+ * + New to FreeRTOS, *\r
+ * + Wanting to learn FreeRTOS or multitasking in general quickly *\r
+ * + Looking for basic training, *\r
+ * + Wanting to improve your FreeRTOS skills and productivity *\r
+ * *\r
+ * then take a look at the FreeRTOS eBook *\r
+ * *\r
+ * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ * A pdf reference manual is also available. Both are usually delivered *\r
+ * to your inbox within 20 minutes to two hours when purchased between 8am *\r
+ * and 8pm GMT (although please allow up to 24 hours in case of *\r
+ * exceptional circumstances). Thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ ***NOTE*** The exception to the GPL is included to allow you to distribute\r
+ a combined work that includes FreeRTOS without being obliged to provide the\r
+ source code for proprietary components outside of the FreeRTOS kernel.\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public \r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it \r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained \r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+/* FreeRTOS.org includes. */\r
+#include "FreeRTOS.h"\r
+\r
+/* Demo application includes. */\r
+#include "partest.h"\r
+\r
+#define partstFIRST_IO ( ( unsigned long ) 0x04 )\r
+#define partstFIO2_BITS ( ( unsigned long ) 0x0000007C )\r
+#define partstFIO1_BITS ( ( unsigned long ) 0xB0000000 )\r
+#define partstNUM_LEDS ( 5 )\r
+#define partstALL_OUTPUTS_OFF ( ( unsigned long ) 0xff )\r
+\r
+/*-----------------------------------------------------------\r
+ * Simple parallel port IO routines.\r
+ *-----------------------------------------------------------*/\r
+\r
+void vParTestInitialise( void )\r
+{\r
+ /* LEDs on ports 1 and 2 to output. */\r
+ GPIO2->FIODIR = partstFIO2_BITS;\r
+ GPIO1->FIODIR = partstFIO1_BITS;\r
+\r
+ /* Start will all LEDs off. */\r
+ GPIO2->FIOCLR = partstFIO2_BITS;\r
+ GPIO1->FIOCLR = partstFIO1_BITS;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vParTestSetLED( unsigned long ulLEDIn, signed long xValue )\r
+{\r
+unsigned long ulLED = partstFIRST_IO;\r
+\r
+ /* Used to set and clear LEDs on FIO2. */\r
+\r
+ if( ulLEDIn < partstNUM_LEDS )\r
+ {\r
+ /* Rotate to the wanted bit of port */\r
+ ulLED <<= ( unsigned long ) ulLEDIn;\r
+\r
+ /* Set of clear the output. */\r
+ if( xValue )\r
+ {\r
+ GPIO2->FIOCLR = ulLED;\r
+ }\r
+ else\r
+ {\r
+ GPIO2->FIOSET = ulLED;\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vParTestToggleLED( unsigned long ulLEDIn )\r
+{\r
+unsigned long ulLED = partstFIRST_IO, ulCurrentState;\r
+\r
+ /* Used to toggle LEDs on FIO2. */\r
+\r
+ if( ulLEDIn < partstNUM_LEDS )\r
+ {\r
+ /* Rotate to the wanted bit of port 0. Only P10 to P13 have an LED\r
+ attached. */\r
+ ulLED <<= ( unsigned long ) ulLEDIn;\r
+\r
+ /* If this bit is already set, clear it, and visa versa. */\r
+ ulCurrentState = GPIO2->FIOPIN;\r
+ if( ulCurrentState & ulLED )\r
+ {\r
+ GPIO2->FIOCLR = ulLED;\r
+ }\r
+ else\r
+ {\r
+ GPIO2->FIOSET = ulLED;\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+long lParTestGetLEDState( void )\r
+{\r
+ /* Returns the state of the LEDs on FIO1. */\r
+ if( ( GPIO1->FIOPIN & partstFIO1_BITS ) != 0 )\r
+ {\r
+ return pdFALSE;\r
+ }\r
+ else\r
+ {\r
+ return pdTRUE;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vParTestSetLEDState( long lState )\r
+{\r
+ /* Used to set and clear the LEDs on FIO1. */\r
+ if( lState != pdFALSE )\r
+ {\r
+ GPIO1->FIOSET = partstFIO1_BITS;\r
+ }\r
+ else\r
+ {\r
+ GPIO1->FIOCLR = partstFIO1_BITS;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V6.0.2 - Copyright (C) 2010 Real Time Engineers Ltd.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * If you are: *\r
+ * *\r
+ * + New to FreeRTOS, *\r
+ * + Wanting to learn FreeRTOS or multitasking in general quickly *\r
+ * + Looking for basic training, *\r
+ * + Wanting to improve your FreeRTOS skills and productivity *\r
+ * *\r
+ * then take a look at the FreeRTOS eBook *\r
+ * *\r
+ * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ * A pdf reference manual is also available. Both are usually delivered *\r
+ * to your inbox within 20 minutes to two hours when purchased between 8am *\r
+ * and 8pm GMT (although please allow up to 24 hours in case of *\r
+ * exceptional circumstances). Thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ ***NOTE*** The exception to the GPL is included to allow you to distribute\r
+ a combined work that includes FreeRTOS without being obliged to provide the\r
+ source code for proprietary components outside of the FreeRTOS kernel.\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public \r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it \r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained \r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+/* FreeRTOS.org includes. */\r
+#include "FreeRTOS.h"\r
+\r
+/* Demo application includes. */\r
+#include "partest.h"\r
+\r
+#define partstFIRST_IO ( ( unsigned long ) 0x04 )\r
+#define partstFIO2_BITS ( ( unsigned long ) 0x0000007C )\r
+#define partstFIO1_BITS ( ( unsigned long ) 0xB0000000 )\r
+#define partstNUM_LEDS ( 5 )\r
+#define partstALL_OUTPUTS_OFF ( ( unsigned long ) 0xff )\r
+\r
+/*-----------------------------------------------------------\r
+ * Simple parallel port IO routines.\r
+ *-----------------------------------------------------------*/\r
+\r
+void vParTestInitialise( void )\r
+{\r
+ /* LEDs on ports 1 and 2 to output. */\r
+ GPIO2->FIODIR = partstFIO2_BITS;\r
+ GPIO1->FIODIR = partstFIO1_BITS;\r
+\r
+ /* Start will all LEDs off. */\r
+ GPIO2->FIOCLR = partstFIO2_BITS;\r
+ GPIO1->FIOCLR = partstFIO1_BITS;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vParTestSetLED( unsigned long ulLEDIn, signed long xValue )\r
+{\r
+unsigned long ulLED = partstFIRST_IO;\r
+\r
+ /* Used to set and clear LEDs on FIO2. */\r
+\r
+ if( ulLEDIn < partstNUM_LEDS )\r
+ {\r
+ /* Rotate to the wanted bit of port */\r
+ ulLED <<= ( unsigned long ) ulLEDIn;\r
+\r
+ /* Set of clear the output. */\r
+ if( xValue )\r
+ {\r
+ GPIO2->FIOCLR = ulLED;\r
+ }\r
+ else\r
+ {\r
+ GPIO2->FIOSET = ulLED;\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vParTestToggleLED( unsigned long ulLEDIn )\r
+{\r
+unsigned long ulLED = partstFIRST_IO, ulCurrentState;\r
+\r
+ /* Used to toggle LEDs on FIO2. */\r
+\r
+ if( ulLEDIn < partstNUM_LEDS )\r
+ {\r
+ /* Rotate to the wanted bit of port 0. Only P10 to P13 have an LED\r
+ attached. */\r
+ ulLED <<= ( unsigned long ) ulLEDIn;\r
+\r
+ /* If this bit is already set, clear it, and visa versa. */\r
+ ulCurrentState = GPIO2->FIOPIN;\r
+ if( ulCurrentState & ulLED )\r
+ {\r
+ GPIO2->FIOCLR = ulLED;\r
+ }\r
+ else\r
+ {\r
+ GPIO2->FIOSET = ulLED;\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+long lParTestGetLEDState( void )\r
+{\r
+ /* Returns the state of the LEDs on FIO1. */\r
+ if( ( GPIO1->FIOPIN & partstFIO1_BITS ) != 0 )\r
+ {\r
+ return pdFALSE;\r
+ }\r
+ else\r
+ {\r
+ return pdTRUE;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vParTestSetLEDState( long lState )\r
+{\r
+ /* Used to set and clear the LEDs on FIO1. */\r
+ if( lState != pdFALSE )\r
+ {\r
+ GPIO1->FIOSET = partstFIO1_BITS;\r
+ }\r
+ else\r
+ {\r
+ GPIO1->FIOCLR = partstFIO1_BITS;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
--- /dev/null
+<!DOCTYPE CrossStudio_Project_File>
+<solution Name="RTOSDemo" version="2">
+ <project Name="RTOSDemo">
+ <configuration Name="Common" Target="LPC1768" arm_architecture="v7M" arm_core_type="Cortex-M3" arm_linker_heap_size="128" arm_linker_process_stack_size="0" arm_linker_stack_size="128" arm_simulator_memory_simulation_filename="$(TargetsDir)/LPC1000/LPC1000SimulatorMemory.dll" arm_simulator_memory_simulation_parameter="0x80000;0x8000;0x8000" arm_target_debug_interface_type="ADIv5" arm_target_loader_parameter="12000000" c_enforce_ansi_checking="No" c_only_additional_options="-Wall;-Wextra" c_preprocessor_definitions="PACK_STRUCT_END=__attribute((packed));ALIGN_STRUCT_END=__attribute((aligned(4)));CONFIGURE_USB;FULL_SPEED" c_user_include_directories="$(TargetsDir)/LPC1000/include;../../Source/include;../Common/include;../../Source/portable/GCC/ARM_CM3;../Common/ethernet/uIP/uip-1.0/uip;.;./webserver;./LPCUSB;./FatFs-port-files;../Common/FileSystem/FatFs-0.7e/src" link_include_startup_code="No" linker_additional_files="$(TargetsDir)/LPC1000/lib/liblpc1000$(LibExt)$(LIB);$(TargetsDir)/LPC1000/lib/cmsis$(LibExt)$(LIB)" linker_memory_map_file="$(TargetsDir)/LPC1000/LPC1768_MemoryMap.xml" linker_printf_fmt_level="int" linker_printf_width_precision_supported="No" linker_section_placement_file="$(ProjectDir)/flash_placement.xml" oscillator_frequency="12MHz" project_directory="" project_type="Executable" property_groups_file_path="$(TargetsDir)/LPC1000/propertyGroups.xml"/>
+ <configuration Name="RAM" Placement="RAM" linker_section_placement_file="$(StudioDir)/targets/Cortex_M/ram_placement.xml" target_reset_script="SRAMReset()"/>
+ <configuration Name="Flash" Placement="Flash" arm_target_flash_loader_file_path="$(TargetsDir)/LPC1000/Release/Loader_rpc.elf" arm_target_flash_loader_type="LIBMEM RPC Loader" linker_patch_build_command="$(StudioDir)/bin/crossscript "load(\"$(TargetsDir)/LPC1000/LPC1000_LinkPatch.js\");patch(\"$(TargetPath)\");"" linker_section_placement_file="$(ProjectDir)/flash_placement.xml" target_reset_script="FLASHReset()"/>
+ <folder Name="Source Files">
+ <configuration Name="Common" filter="c;cpp;cxx;cc;h;s;asm;inc"/>
+ <folder Name="FreeRTOS">
+ <file file_name="../../Source/tasks.c"/>
+ <file file_name="../../Source/list.c"/>
+ <file file_name="../../Source/queue.c"/>
+ <file file_name="../../Source/portable/GCC/ARM_CM3/port.c"/>
+ <file file_name="../../Source/portable/MemMang/heap_2.c"/>
+ </folder>
+ <folder Name="Common Demo Tasks">
+ <file file_name="../Common/Minimal/recmutex.c"/>
+ <file file_name="../Common/Minimal/semtest.c"/>
+ <file file_name="../Common/Minimal/BlockQ.c"/>
+ <file file_name="../Common/Minimal/blocktim.c"/>
+ <file file_name="../Common/Minimal/flash.c"/>
+ <file file_name="../Common/Minimal/GenQTest.c"/>
+ <file file_name="../Common/Minimal/integer.c"/>
+ <file file_name="../Common/Minimal/QPeek.c"/>
+ <file file_name="../Common/Minimal/PollQ.c"/>
+ </folder>
+ <file file_name="main.c"/>
+ <folder Name="WEB Server" file_name="">
+ <file file_name="../Common/ethernet/uIP/uip-1.0/uip/uip.c"/>
+ <file file_name="../Common/ethernet/uIP/uip-1.0/uip/uip_arp.c"/>
+ <file file_name="../Common/ethernet/uIP/uip-1.0/uip/psock.c"/>
+ <file file_name="../Common/ethernet/uIP/uip-1.0/uip/timer.c"/>
+ <file file_name="webserver/uIP_Task.c"/>
+ <file file_name="webserver/emac.c">
+ <configuration Name="THUMB Flash Debug" build_exclude_from_build="No"/>
+ </file>
+ <file file_name="webserver/httpd.c"/>
+ <file file_name="webserver/httpd-cgi.c"/>
+ <file file_name="webserver/httpd-fs.c"/>
+ <file file_name="webserver/http-strings.c"/>
+ </folder>
+ <file file_name="ParTest.c"/>
+ <file file_name="printf-stdarg.c"/>
+ <folder Name="LPCUSB">
+ <file file_name="LPCUSB/usbstdreq.c"/>
+ <file file_name="LPCUSB/USB_CDC.c"/>
+ <file file_name="LPCUSB/usbcontrol.c"/>
+ <file file_name="LPCUSB/usbhw_lpc.c"/>
+ <file file_name="LPCUSB/usbinit.c"/>
+ </folder>
+ <folder Name="FatFS">
+ <file file_name="../Common/FileSystem/FatFs-0.7e/src/ff.c"/>
+ <file file_name="../Common/FileSystem/FatFs-0.7e/src/option/syncobj.c"/>
+ <file file_name="FatFs-port-files/diskio.c"/>
+ </folder>
+ </folder>
+ <folder Name="System Files">
+ <file file_name="$(StudioDir)/source/thumb_crt0.s"/>
+ <file file_name="$(TargetsDir)/LPC1000/LPC1700_Target.js">
+ <configuration Name="Common" file_type="Reset Script"/>
+ </file>
+ <file file_name="LPC1700_Startup.s"/>
+ </folder>
+ </project>
+ <configuration Name="THUMB Flash Debug" inherited_configurations="THUMB;Flash;Debug"/>
+ <configuration Name="THUMB" Platform="ARM" arm_instruction_set="THUMB" arm_library_instruction_set="THUMB" c_preprocessor_definitions="__THUMB" hidden="Yes"/>
+ <configuration Name="Flash" c_preprocessor_definitions="__FLASH_BUILD" hidden="Yes"/>
+ <configuration Name="Debug" build_debug_information="Yes" c_preprocessor_definitions="DEBUG" gcc_optimization_level="None" hidden="Yes" link_include_startup_code="No"/>
+ <configuration Name="THUMB Flash Release" inherited_configurations="THUMB;Flash;Release"/>
+ <configuration Name="Release" build_debug_information="No" c_additional_options="-g1" c_preprocessor_definitions="NDEBUG" gcc_optimization_level="Level 1" hidden="Yes" link_include_startup_code="No"/>
+</solution>
--- /dev/null
+<!DOCTYPE CrossStudio_for_ARM_Session_File>
+<session>
+ <Bookmarks/>
+ <Breakpoints>
+ <BreakpointListItem line="1409" action="" hardwareBreakpoint="" trigger="" useHWbreakpoint="false" group="Breakpoints" type="Breakpoint" state="4" counter="0" isFunctionBreakpoint="false" filename="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\Common\FileSystem\FatFs-0.7e\src\ff.c" expression="" />
+ <BreakpointListItem line="271" action="" hardwareBreakpoint="" trigger="" useHWbreakpoint="false" group="Breakpoints" type="Breakpoint" state="2" counter="0" isFunctionBreakpoint="false" filename="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_LPC17xx_Rowley_lwIP_FatFs_USB\main.c" expression="" />
+ <BreakpointListItem line="184" action="" hardwareBreakpoint="" trigger="" useHWbreakpoint="false" group="Breakpoints" type="Breakpoint" state="4" counter="0" isFunctionBreakpoint="false" filename="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\UsbHost\Host\usbhost_lpc17xx.c" expression="" />
+ <BreakpointListItem line="46" action="" hardwareBreakpoint="" trigger="" useHWbreakpoint="false" group="Breakpoints" type="Breakpoint" state="4" counter="0" isFunctionBreakpoint="false" filename="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\UsbHost\Main\usbhost_task.c" expression="" />
+ </Breakpoints>
+ <ExecutionCountWindow/>
+ <Memory1>
+ <MemoryWindow autoEvaluate="0" addressText="0x10003c24" numColumns="8" sizeText="100" dataSize="1" radix="16" addressSpace="" />
+ </Memory1>
+ <Memory2>
+ <MemoryWindow autoEvaluate="0" addressText="" numColumns="8" sizeText="" dataSize="1" radix="16" addressSpace="" />
+ </Memory2>
+ <Memory3>
+ <MemoryWindow autoEvaluate="0" addressText="" numColumns="8" sizeText="" dataSize="1" radix="16" addressSpace="" />
+ </Memory3>
+ <Memory4>
+ <MemoryWindow autoEvaluate="0" addressText="" numColumns="8" sizeText="" dataSize="1" radix="16" addressSpace="" />
+ </Memory4>
+ <Project>
+ <ProjectSessionItem path="RTOSDemo" name="unnamed" />
+ <ProjectSessionItem path="RTOSDemo;RTOSDemo" name="unnamed" />
+ <ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files" name="unnamed" />
+ <ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;FatFS" name="unnamed" />
+ <ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;WEB Server" name="unnamed" />
+ </Project>
+ <Register1>
+ <RegisterWindow openNodes="CPU;CPU/xPSR;CPU/CFBP;CPU/CFBP/CONTROL[0];CPU/CFBP/CONTROL[1]" binaryNodes="" unsignedNodes="" visibleGroups="CPU" decimalNodes="" octalNodes="" asciiNodes="" />
+ </Register1>
+ <Register2>
+ <RegisterWindow openNodes="SPI0/S0SPCR;SPI0/S0SPSR;SC" binaryNodes="" unsignedNodes="" visibleGroups="SPI0;SC;GPIO" decimalNodes="" octalNodes="" asciiNodes="" />
+ </Register2>
+ <Register3>
+ <RegisterWindow openNodes="" binaryNodes="" unsignedNodes="" visibleGroups="" decimalNodes="" octalNodes="" asciiNodes="" />
+ </Register3>
+ <Register4>
+ <RegisterWindow openNodes="" binaryNodes="" unsignedNodes="" visibleGroups="" decimalNodes="" octalNodes="" asciiNodes="" />
+ </Register4>
+ <TargetWindow programAction="" uploadFileType="" programLoadAddress="" programSize="" uploadFileName="" uploadMemoryInterface="" programFileName="" uploadStartAddress="" programFileType="" uploadSize="" programMemoryInterface="" />
+ <TraceWindow>
+ <Trace enabled="Yes" />
+ </TraceWindow>
+ <Watch1>
+ <Watches active="1" update="Never" >
+ <Watchpoint evalMode="3" linenumber="0" evalType="0" radix="16" name="c" expression="c" filename="" />
+ </Watches>
+ </Watch1>
+ <Watch2>
+ <Watches active="0" update="Never" />
+ </Watch2>
+ <Watch3>
+ <Watches active="0" update="Never" />
+ </Watch3>
+ <Watch4>
+ <Watches active="0" update="Never" />
+ </Watch4>
+ <Files>
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_LPC17xx_Rowley_lwIP_FatFs_USB\webserver\httpd-fs.c" y="0" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_LPC17xx_Rowley_lwIP_FatFs_USB\webserver\httpd-fs.c" left="0" selected="0" name="unnamed" top="93" />
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_LPC17xx_Rowley_lwIP_FatFs_USB\webserver\httpd-fsdata.c" y="0" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_LPC17xx_Rowley_lwIP_FatFs_USB\webserver\httpd-fsdata.c" left="0" selected="0" name="unnamed" top="518" />
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="40" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_LPC17xx_Rowley_lwIP_FatFs_USB\webserver\httpd.c" y="81" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_LPC17xx_Rowley_lwIP_FatFs_USB\webserver\httpd.c" left="0" selected="0" name="unnamed" top="57" />
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_LPC17xx_Rowley_lwIP_FatFs_USB\webserver\uIP_Task.c" y="0" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_LPC17xx_Rowley_lwIP_FatFs_USB\webserver\uIP_Task.c" left="0" selected="0" name="unnamed" top="184" />
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_LPC17xx_Rowley_lwIP_FatFs_USB\FatFs-port-files\diskio.c" y="750" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_LPC17xx_Rowley_lwIP_FatFs_USB\FatFs-port-files\diskio.c" left="0" selected="1" name="unnamed" top="733" />
+ </Files>
+ <ARMCrossStudioWindow activeProject="RTOSDemo" autoConnectTarget="USB CrossConnect for ARM" debugSearchFileMap="" fileDialogInitialDirectory="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_LPC17xx_Rowley_lwIP_FatFs_USB\FatFs-port-files" fileDialogDefaultFilter="*.*" autoConnectCapabilities="388991" debugSearchPath="" buildConfiguration="THUMB Flash Debug" />
+</session>
--- /dev/null
+/******************************************************************************\r
+ * @file: core_cm3.h\r
+ * @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Header File\r
+ * @version: V1.20\r
+ * @date: 22. May 2009\r
+ *----------------------------------------------------------------------------\r
+ *\r
+ * Copyright (C) 2009 ARM Limited. All rights reserved.\r
+ *\r
+ * ARM Limited (ARM) is supplying this software for use with Cortex-Mx \r
+ * processor based microcontrollers. This file can be freely distributed \r
+ * within development tools that are supporting such ARM based processors. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
+ *\r
+ ******************************************************************************/\r
+\r
+#ifndef __CM3_CORE_H__\r
+#define __CM3_CORE_H__\r
+\r
+#ifdef __cplusplus\r
+ extern "C" {\r
+#endif \r
+\r
+#define __CM3_CMSIS_VERSION_MAIN (0x01) /*!< [31:16] CMSIS HAL main version */\r
+#define __CM3_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */\r
+#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */\r
+\r
+#define __CORTEX_M (0x03) /*!< Cortex core */\r
+\r
+/**\r
+ * Lint configuration \n\r
+ * ----------------------- \n\r
+ *\r
+ * The following Lint messages will be suppressed and not shown: \n\r
+ * \n\r
+ * --- Error 10: --- \n\r
+ * register uint32_t __regBasePri __asm("basepri"); \n\r
+ * Error 10: Expecting ';' \n\r
+ * \n\r
+ * --- Error 530: --- \n\r
+ * return(__regBasePri); \n\r
+ * Warning 530: Symbol '__regBasePri' (line 264) not initialized \n\r
+ * \n\r
+ * --- Error 550: --- \n\r
+ * __regBasePri = (basePri & 0x1ff); \n\r
+ * } \n\r
+ * Warning 550: Symbol '__regBasePri' (line 271) not accessed \n\r
+ * \n\r
+ * --- Error 754: --- \n\r
+ * uint32_t RESERVED0[24]; \n\r
+ * Info 754: local structure member '<some, not used in the HAL>' (line 109, file ./cm3_core.h) not referenced \n\r
+ * \n\r
+ * --- Error 750: --- \n\r
+ * #define __CM3_CORE_H__ \n\r
+ * Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced \n\r
+ * \n\r
+ * --- Error 528: --- \n\r
+ * static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n\r
+ * Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced \n\r
+ * \n\r
+ * --- Error 751: --- \n\r
+ * } InterruptType_Type; \n\r
+ * Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced \n\r
+ * \n\r
+ * \n\r
+ * Note: To re-enable a Message, insert a space before 'lint' * \n\r
+ *\r
+ */\r
+\r
+/*lint -save */\r
+/*lint -e10 */\r
+/*lint -e530 */\r
+/*lint -e550 */\r
+/*lint -e754 */\r
+/*lint -e750 */\r
+/*lint -e528 */\r
+/*lint -e751 */\r
+\r
+\r
+#include <stdint.h> /* Include standard types */\r
+\r
+#if defined (__ICCARM__)\r
+ #include <intrinsics.h> /* IAR Intrinsics */\r
+#endif\r
+\r
+\r
+#ifndef __NVIC_PRIO_BITS\r
+ #define __NVIC_PRIO_BITS 4 /*!< standard definition for NVIC Priority Bits */\r
+#endif\r
+\r
+\r
+\r
+\r
+/**\r
+ * IO definitions\r
+ *\r
+ * define access restrictions to peripheral registers\r
+ */\r
+\r
+#ifdef __cplusplus\r
+#define __I volatile /*!< defines 'read only' permissions */\r
+#else\r
+#define __I volatile const /*!< defines 'read only' permissions */\r
+#endif\r
+#define __O volatile /*!< defines 'write only' permissions */\r
+#define __IO volatile /*!< defines 'read / write' permissions */\r
+\r
+\r
+\r
+/*******************************************************************************\r
+ * Register Abstraction\r
+ ******************************************************************************/\r
+\r
+\r
+/* System Reset */\r
+#define NVIC_VECTRESET 0 /*!< Vector Reset Bit */\r
+#define NVIC_SYSRESETREQ 2 /*!< System Reset Request */\r
+#define NVIC_AIRCR_VECTKEY (0x5FA << 16) /*!< AIRCR Key for write access */\r
+#define NVIC_AIRCR_ENDIANESS 15 /*!< Endianess */\r
+\r
+/* Core Debug */\r
+#define CoreDebug_DEMCR_TRCENA (1 << 24) /*!< DEMCR TRCENA enable */\r
+#define ITM_TCR_ITMENA 1 /*!< ITM enable */\r
+\r
+\r
+\r
+\r
+/* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */\r
+typedef struct\r
+{\r
+ __IO uint32_t ISER[8]; /*!< Interrupt Set Enable Register */\r
+ uint32_t RESERVED0[24];\r
+ __IO uint32_t ICER[8]; /*!< Interrupt Clear Enable Register */\r
+ uint32_t RSERVED1[24];\r
+ __IO uint32_t ISPR[8]; /*!< Interrupt Set Pending Register */\r
+ uint32_t RESERVED2[24];\r
+ __IO uint32_t ICPR[8]; /*!< Interrupt Clear Pending Register */\r
+ uint32_t RESERVED3[24];\r
+ __IO uint32_t IABR[8]; /*!< Interrupt Active bit Register */\r
+ uint32_t RESERVED4[56];\r
+ __IO uint8_t IP[240]; /*!< Interrupt Priority Register, 8Bit wide */\r
+ uint32_t RESERVED5[644];\r
+ __O uint32_t STIR; /*!< Software Trigger Interrupt Register */\r
+} NVIC_Type;\r
+\r
+\r
+/* memory mapping struct for System Control Block */\r
+typedef struct\r
+{\r
+ __I uint32_t CPUID; /*!< CPU ID Base Register */\r
+ __IO uint32_t ICSR; /*!< Interrupt Control State Register */\r
+ __IO uint32_t VTOR; /*!< Vector Table Offset Register */\r
+ __IO uint32_t AIRCR; /*!< Application Interrupt / Reset Control Register */\r
+ __IO uint32_t SCR; /*!< System Control Register */\r
+ __IO uint32_t CCR; /*!< Configuration Control Register */\r
+ __IO uint8_t SHP[12]; /*!< System Handlers Priority Registers (4-7, 8-11, 12-15) */\r
+ __IO uint32_t SHCSR; /*!< System Handler Control and State Register */\r
+ __IO uint32_t CFSR; /*!< Configurable Fault Status Register */\r
+ __IO uint32_t HFSR; /*!< Hard Fault Status Register */\r
+ __IO uint32_t DFSR; /*!< Debug Fault Status Register */\r
+ __IO uint32_t MMFAR; /*!< Mem Manage Address Register */\r
+ __IO uint32_t BFAR; /*!< Bus Fault Address Register */\r
+ __IO uint32_t AFSR; /*!< Auxiliary Fault Status Register */\r
+ __I uint32_t PFR[2]; /*!< Processor Feature Register */\r
+ __I uint32_t DFR; /*!< Debug Feature Register */\r
+ __I uint32_t ADR; /*!< Auxiliary Feature Register */\r
+ __I uint32_t MMFR[4]; /*!< Memory Model Feature Register */\r
+ __I uint32_t ISAR[5]; /*!< ISA Feature Register */\r
+} SCB_Type;\r
+\r
+\r
+/* memory mapping struct for SysTick */\r
+typedef struct\r
+{\r
+ __IO uint32_t CTRL; /*!< SysTick Control and Status Register */\r
+ __IO uint32_t LOAD; /*!< SysTick Reload Value Register */\r
+ __IO uint32_t VAL; /*!< SysTick Current Value Register */\r
+ __I uint32_t CALIB; /*!< SysTick Calibration Register */\r
+} SysTick_Type;\r
+\r
+\r
+/* memory mapping structur for ITM */\r
+typedef struct\r
+{\r
+ __O union \r
+ {\r
+ __O uint8_t u8; /*!< ITM Stimulus Port 8-bit */\r
+ __O uint16_t u16; /*!< ITM Stimulus Port 16-bit */\r
+ __O uint32_t u32; /*!< ITM Stimulus Port 32-bit */\r
+ } PORT [32]; /*!< ITM Stimulus Port Registers */\r
+ uint32_t RESERVED0[864];\r
+ __IO uint32_t TER; /*!< ITM Trace Enable Register */\r
+ uint32_t RESERVED1[15];\r
+ __IO uint32_t TPR; /*!< ITM Trace Privilege Register */\r
+ uint32_t RESERVED2[15];\r
+ __IO uint32_t TCR; /*!< ITM Trace Control Register */\r
+ uint32_t RESERVED3[29];\r
+ __IO uint32_t IWR; /*!< ITM Integration Write Register */\r
+ __IO uint32_t IRR; /*!< ITM Integration Read Register */\r
+ __IO uint32_t IMCR; /*!< ITM Integration Mode Control Register */\r
+ uint32_t RESERVED4[43];\r
+ __IO uint32_t LAR; /*!< ITM Lock Access Register */\r
+ __IO uint32_t LSR; /*!< ITM Lock Status Register */\r
+ uint32_t RESERVED5[6];\r
+ __I uint32_t PID4; /*!< ITM Product ID Registers */\r
+ __I uint32_t PID5;\r
+ __I uint32_t PID6;\r
+ __I uint32_t PID7;\r
+ __I uint32_t PID0;\r
+ __I uint32_t PID1;\r
+ __I uint32_t PID2;\r
+ __I uint32_t PID3;\r
+ __I uint32_t CID0;\r
+ __I uint32_t CID1;\r
+ __I uint32_t CID2;\r
+ __I uint32_t CID3;\r
+} ITM_Type;\r
+\r
+\r
+/* memory mapped struct for Interrupt Type */\r
+typedef struct\r
+{\r
+ uint32_t RESERVED0;\r
+ __I uint32_t ICTR; /*!< Interrupt Control Type Register */\r
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))\r
+ __IO uint32_t ACTLR; /*!< Auxiliary Control Register */\r
+#else\r
+ uint32_t RESERVED1;\r
+#endif\r
+} InterruptType_Type;\r
+\r
+\r
+/* Memory Protection Unit */\r
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)\r
+typedef struct\r
+{\r
+ __I uint32_t TYPE; /*!< MPU Type Register */\r
+ __IO uint32_t CTRL; /*!< MPU Control Register */\r
+ __IO uint32_t RNR; /*!< MPU Region RNRber Register */\r
+ __IO uint32_t RBAR; /*!< MPU Region Base Address Register */\r
+ __IO uint32_t RASR; /*!< MPU Region Attribute and Size Register */\r
+ __IO uint32_t RBAR_A1; /*!< MPU Alias 1 Region Base Address Register */\r
+ __IO uint32_t RASR_A1; /*!< MPU Alias 1 Region Attribute and Size Register */\r
+ __IO uint32_t RBAR_A2; /*!< MPU Alias 2 Region Base Address Register */\r
+ __IO uint32_t RASR_A2; /*!< MPU Alias 2 Region Attribute and Size Register */\r
+ __IO uint32_t RBAR_A3; /*!< MPU Alias 3 Region Base Address Register */\r
+ __IO uint32_t RASR_A3; /*!< MPU Alias 3 Region Attribute and Size Register */\r
+} MPU_Type;\r
+#endif\r
+\r
+\r
+/* Core Debug Register */\r
+typedef struct\r
+{\r
+ __IO uint32_t DHCSR; /*!< Debug Halting Control and Status Register */\r
+ __O uint32_t DCRSR; /*!< Debug Core Register Selector Register */\r
+ __IO uint32_t DCRDR; /*!< Debug Core Register Data Register */\r
+ __IO uint32_t DEMCR; /*!< Debug Exception and Monitor Control Register */\r
+} CoreDebug_Type;\r
+\r
+\r
+/* Memory mapping of Cortex-M3 Hardware */\r
+#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */\r
+#define ITM_BASE (0xE0000000) /*!< ITM Base Address */\r
+#define CoreDebug_BASE (0xE000EDF0) /*!< Core Debug Base Address */\r
+#define SysTick_BASE (SCS_BASE + 0x0010) /*!< SysTick Base Address */\r
+#define NVIC_BASE (SCS_BASE + 0x0100) /*!< NVIC Base Address */\r
+#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */\r
+\r
+#define InterruptType ((InterruptType_Type *) SCS_BASE) /*!< Interrupt Type Register */\r
+#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */\r
+#define SysTick ((SysTick_Type *) SysTick_BASE) /*!< SysTick configuration struct */\r
+#define NVIC ((NVIC_Type *) NVIC_BASE) /*!< NVIC configuration struct */\r
+#define ITM ((ITM_Type *) ITM_BASE) /*!< ITM configuration struct */\r
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */\r
+\r
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)\r
+ #define MPU_BASE (SCS_BASE + 0x0D90) /*!< Memory Protection Unit */\r
+ #define MPU ((MPU_Type*) MPU_BASE) /*!< Memory Protection Unit */\r
+#endif\r
+\r
+\r
+\r
+/*******************************************************************************\r
+ * Hardware Abstraction Layer\r
+ ******************************************************************************/\r
+\r
+\r
+#if defined ( __CC_ARM )\r
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */\r
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */\r
+\r
+#elif defined ( __ICCARM__ )\r
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */\r
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */\r
+\r
+#elif defined ( __GNUC__ )\r
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */\r
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */\r
+\r
+#elif defined ( __TASKING__ )\r
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */\r
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */\r
+\r
+#endif\r
+\r
+\r
+/* ################### Compiler specific Intrinsics ########################### */\r
+\r
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/\r
+/* ARM armcc specific functions */\r
+\r
+#define __enable_fault_irq __enable_fiq\r
+#define __disable_fault_irq __disable_fiq\r
+\r
+#define __NOP __nop\r
+#define __WFI __wfi\r
+#define __WFE __wfe\r
+#define __SEV __sev\r
+#define __ISB() __isb(0)\r
+#define __DSB() __dsb(0)\r
+#define __DMB() __dmb(0)\r
+#define __REV __rev\r
+#define __RBIT __rbit\r
+#define __LDREXB(ptr) ((unsigned char ) __ldrex(ptr))\r
+#define __LDREXH(ptr) ((unsigned short) __ldrex(ptr))\r
+#define __LDREXW(ptr) ((unsigned int ) __ldrex(ptr))\r
+#define __STREXB(value, ptr) __strex(value, ptr)\r
+#define __STREXH(value, ptr) __strex(value, ptr)\r
+#define __STREXW(value, ptr) __strex(value, ptr)\r
+\r
+\r
+/* intrinsic unsigned long long __ldrexd(volatile void *ptr) */\r
+/* intrinsic int __strexd(unsigned long long val, volatile void *ptr) */\r
+/* intrinsic void __enable_irq(); */\r
+/* intrinsic void __disable_irq(); */\r
+\r
+\r
+/**\r
+ * @brief Return the Process Stack Pointer\r
+ *\r
+ * @param none\r
+ * @return uint32_t ProcessStackPointer\r
+ *\r
+ * Return the actual process stack pointer\r
+ */\r
+extern uint32_t __get_PSP(void);\r
+\r
+/**\r
+ * @brief Set the Process Stack Pointer\r
+ *\r
+ * @param uint32_t Process Stack Pointer\r
+ * @return none\r
+ *\r
+ * Assign the value ProcessStackPointer to the MSP \r
+ * (process stack pointer) Cortex processor register\r
+ */\r
+extern void __set_PSP(uint32_t topOfProcStack);\r
+\r
+/**\r
+ * @brief Return the Main Stack Pointer\r
+ *\r
+ * @param none\r
+ * @return uint32_t Main Stack Pointer\r
+ *\r
+ * Return the current value of the MSP (main stack pointer)\r
+ * Cortex processor register\r
+ */\r
+extern uint32_t __get_MSP(void);\r
+\r
+/**\r
+ * @brief Set the Main Stack Pointer\r
+ *\r
+ * @param uint32_t Main Stack Pointer\r
+ * @return none\r
+ *\r
+ * Assign the value mainStackPointer to the MSP \r
+ * (main stack pointer) Cortex processor register\r
+ */\r
+extern void __set_MSP(uint32_t topOfMainStack);\r
+\r
+/**\r
+ * @brief Reverse byte order in unsigned short value\r
+ *\r
+ * @param uint16_t value to reverse\r
+ * @return uint32_t reversed value\r
+ *\r
+ * Reverse byte order in unsigned short value\r
+ */\r
+extern uint32_t __REV16(uint16_t value);\r
+\r
+/*\r
+ * @brief Reverse byte order in signed short value with sign extension to integer\r
+ *\r
+ * @param int16_t value to reverse\r
+ * @return int32_t reversed value\r
+ *\r
+ * Reverse byte order in signed short value with sign extension to integer\r
+ */\r
+extern int32_t __REVSH(int16_t value);\r
+\r
+\r
+#if (__ARMCC_VERSION < 400000)\r
+\r
+/**\r
+ * @brief Remove the exclusive lock created by ldrex\r
+ *\r
+ * @param none\r
+ * @return none\r
+ *\r
+ * Removes the exclusive lock which is created by ldrex.\r
+ */\r
+extern void __CLREX(void);\r
+\r
+/**\r
+ * @brief Return the Base Priority value\r
+ *\r
+ * @param none\r
+ * @return uint32_t BasePriority\r
+ *\r
+ * Return the content of the base priority register\r
+ */\r
+extern uint32_t __get_BASEPRI(void);\r
+\r
+/**\r
+ * @brief Set the Base Priority value\r
+ *\r
+ * @param uint32_t BasePriority\r
+ * @return none\r
+ *\r
+ * Set the base priority register\r
+ */\r
+extern void __set_BASEPRI(uint32_t basePri);\r
+\r
+/**\r
+ * @brief Return the Priority Mask value\r
+ *\r
+ * @param none\r
+ * @return uint32_t PriMask\r
+ *\r
+ * Return the state of the priority mask bit from the priority mask\r
+ * register\r
+ */\r
+extern uint32_t __get_PRIMASK(void);\r
+\r
+/**\r
+ * @brief Set the Priority Mask value\r
+ *\r
+ * @param uint32_t PriMask\r
+ * @return none\r
+ *\r
+ * Set the priority mask bit in the priority mask register\r
+ */\r
+extern void __set_PRIMASK(uint32_t priMask);\r
+\r
+/**\r
+ * @brief Return the Fault Mask value\r
+ *\r
+ * @param none\r
+ * @return uint32_t FaultMask\r
+ *\r
+ * Return the content of the fault mask register\r
+ */\r
+extern uint32_t __get_FAULTMASK(void);\r
+\r
+/**\r
+ * @brief Set the Fault Mask value\r
+ *\r
+ * @param uint32_t faultMask value\r
+ * @return none\r
+ *\r
+ * Set the fault mask register\r
+ */\r
+extern void __set_FAULTMASK(uint32_t faultMask);\r
+\r
+/**\r
+ * @brief Return the Control Register value\r
+ * \r
+ * @param none\r
+ * @return uint32_t Control value\r
+ *\r
+ * Return the content of the control register\r
+ */\r
+extern uint32_t __get_CONTROL(void);\r
+\r
+/**\r
+ * @brief Set the Control Register value\r
+ *\r
+ * @param uint32_t Control value\r
+ * @return none\r
+ *\r
+ * Set the control register\r
+ */\r
+extern void __set_CONTROL(uint32_t control);\r
+\r
+#else /* (__ARMCC_VERSION >= 400000) */\r
+\r
+\r
+/**\r
+ * @brief Remove the exclusive lock created by ldrex\r
+ *\r
+ * @param none\r
+ * @return none\r
+ *\r
+ * Removes the exclusive lock which is created by ldrex.\r
+ */\r
+#define __CLREX __clrex\r
+\r
+/**\r
+ * @brief Return the Base Priority value\r
+ *\r
+ * @param none\r
+ * @return uint32_t BasePriority\r
+ *\r
+ * Return the content of the base priority register\r
+ */\r
+static __INLINE uint32_t __get_BASEPRI(void)\r
+{\r
+ register uint32_t __regBasePri __ASM("basepri");\r
+ return(__regBasePri);\r
+}\r
+\r
+/**\r
+ * @brief Set the Base Priority value\r
+ *\r
+ * @param uint32_t BasePriority\r
+ * @return none\r
+ *\r
+ * Set the base priority register\r
+ */\r
+static __INLINE void __set_BASEPRI(uint32_t basePri)\r
+{\r
+ register uint32_t __regBasePri __ASM("basepri");\r
+ __regBasePri = (basePri & 0x1ff);\r
+}\r
+\r
+/**\r
+ * @brief Return the Priority Mask value\r
+ *\r
+ * @param none\r
+ * @return uint32_t PriMask\r
+ *\r
+ * Return the state of the priority mask bit from the priority mask\r
+ * register\r
+ */\r
+static __INLINE uint32_t __get_PRIMASK(void)\r
+{\r
+ register uint32_t __regPriMask __ASM("primask");\r
+ return(__regPriMask);\r
+}\r
+\r
+/**\r
+ * @brief Set the Priority Mask value\r
+ *\r
+ * @param uint32_t PriMask\r
+ * @return none\r
+ *\r
+ * Set the priority mask bit in the priority mask register\r
+ */\r
+static __INLINE void __set_PRIMASK(uint32_t priMask)\r
+{\r
+ register uint32_t __regPriMask __ASM("primask");\r
+ __regPriMask = (priMask);\r
+}\r
+\r
+/**\r
+ * @brief Return the Fault Mask value\r
+ *\r
+ * @param none\r
+ * @return uint32_t FaultMask\r
+ *\r
+ * Return the content of the fault mask register\r
+ */\r
+static __INLINE uint32_t __get_FAULTMASK(void)\r
+{\r
+ register uint32_t __regFaultMask __ASM("faultmask");\r
+ return(__regFaultMask);\r
+}\r
+\r
+/**\r
+ * @brief Set the Fault Mask value\r
+ *\r
+ * @param uint32_t faultMask value\r
+ * @return none\r
+ *\r
+ * Set the fault mask register\r
+ */\r
+static __INLINE void __set_FAULTMASK(uint32_t faultMask)\r
+{\r
+ register uint32_t __regFaultMask __ASM("faultmask");\r
+ __regFaultMask = (faultMask & 1);\r
+}\r
+\r
+/**\r
+ * @brief Return the Control Register value\r
+ * \r
+ * @param none\r
+ * @return uint32_t Control value\r
+ *\r
+ * Return the content of the control register\r
+ */\r
+static __INLINE uint32_t __get_CONTROL(void)\r
+{\r
+ register uint32_t __regControl __ASM("control");\r
+ return(__regControl);\r
+}\r
+\r
+/**\r
+ * @brief Set the Control Register value\r
+ *\r
+ * @param uint32_t Control value\r
+ * @return none\r
+ *\r
+ * Set the control register\r
+ */\r
+static __INLINE void __set_CONTROL(uint32_t control)\r
+{\r
+ register uint32_t __regControl __ASM("control");\r
+ __regControl = control;\r
+}\r
+\r
+#endif /* __ARMCC_VERSION */ \r
+\r
+\r
+\r
+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/\r
+/* IAR iccarm specific functions */\r
+\r
+#define __enable_irq __enable_interrupt /*!< global Interrupt enable */\r
+#define __disable_irq __disable_interrupt /*!< global Interrupt disable */\r
+\r
+static __INLINE void __enable_fault_irq() { __ASM ("cpsie f"); }\r
+static __INLINE void __disable_fault_irq() { __ASM ("cpsid f"); }\r
+\r
+#define __NOP __no_operation() /*!< no operation intrinsic in IAR Compiler */ \r
+static __INLINE void __WFI() { __ASM ("wfi"); }\r
+static __INLINE void __WFE() { __ASM ("wfe"); }\r
+static __INLINE void __SEV() { __ASM ("sev"); }\r
+static __INLINE void __CLREX() { __ASM ("clrex"); }\r
+\r
+/* intrinsic void __ISB(void) */\r
+/* intrinsic void __DSB(void) */\r
+/* intrinsic void __DMB(void) */\r
+/* intrinsic void __set_PRIMASK(); */\r
+/* intrinsic void __get_PRIMASK(); */\r
+/* intrinsic void __set_FAULTMASK(); */\r
+/* intrinsic void __get_FAULTMASK(); */\r
+/* intrinsic uint32_t __REV(uint32_t value); */\r
+/* intrinsic uint32_t __REVSH(uint32_t value); */\r
+/* intrinsic unsigned long __STREX(unsigned long, unsigned long); */\r
+/* intrinsic unsigned long __LDREX(unsigned long *); */\r
+\r
+\r
+/**\r
+ * @brief Return the Process Stack Pointer\r
+ *\r
+ * @param none\r
+ * @return uint32_t ProcessStackPointer\r
+ *\r
+ * Return the actual process stack pointer\r
+ */\r
+extern uint32_t __get_PSP(void);\r
+\r
+/**\r
+ * @brief Set the Process Stack Pointer\r
+ *\r
+ * @param uint32_t Process Stack Pointer\r
+ * @return none\r
+ *\r
+ * Assign the value ProcessStackPointer to the MSP \r
+ * (process stack pointer) Cortex processor register\r
+ */\r
+extern void __set_PSP(uint32_t topOfProcStack);\r
+\r
+/**\r
+ * @brief Return the Main Stack Pointer\r
+ *\r
+ * @param none\r
+ * @return uint32_t Main Stack Pointer\r
+ *\r
+ * Return the current value of the MSP (main stack pointer)\r
+ * Cortex processor register\r
+ */\r
+extern uint32_t __get_MSP(void);\r
+\r
+/**\r
+ * @brief Set the Main Stack Pointer\r
+ *\r
+ * @param uint32_t Main Stack Pointer\r
+ * @return none\r
+ *\r
+ * Assign the value mainStackPointer to the MSP \r
+ * (main stack pointer) Cortex processor register\r
+ */\r
+extern void __set_MSP(uint32_t topOfMainStack);\r
+\r
+/**\r
+ * @brief Reverse byte order in unsigned short value\r
+ *\r
+ * @param uint16_t value to reverse\r
+ * @return uint32_t reversed value\r
+ *\r
+ * Reverse byte order in unsigned short value\r
+ */\r
+extern uint32_t __REV16(uint16_t value);\r
+\r
+/**\r
+ * @brief Reverse bit order of value\r
+ *\r
+ * @param uint32_t value to reverse\r
+ * @return uint32_t reversed value\r
+ *\r
+ * Reverse bit order of value\r
+ */\r
+extern uint32_t __RBIT(uint32_t value);\r
+\r
+/**\r
+ * @brief LDR Exclusive\r
+ *\r
+ * @param uint8_t* address\r
+ * @return uint8_t value of (*address)\r
+ *\r
+ * Exclusive LDR command\r
+ */\r
+extern uint8_t __LDREXB(uint8_t *addr);\r
+\r
+/**\r
+ * @brief LDR Exclusive\r
+ *\r
+ * @param uint16_t* address\r
+ * @return uint16_t value of (*address)\r
+ *\r
+ * Exclusive LDR command\r
+ */\r
+extern uint16_t __LDREXH(uint16_t *addr);\r
+\r
+/**\r
+ * @brief LDR Exclusive\r
+ *\r
+ * @param uint32_t* address\r
+ * @return uint32_t value of (*address)\r
+ *\r
+ * Exclusive LDR command\r
+ */\r
+extern uint32_t __LDREXW(uint32_t *addr);\r
+\r
+/**\r
+ * @brief STR Exclusive\r
+ *\r
+ * @param uint8_t *address\r
+ * @param uint8_t value to store\r
+ * @return uint32_t successful / failed\r
+ *\r
+ * Exclusive STR command\r
+ */\r
+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);\r
+\r
+/**\r
+ * @brief STR Exclusive\r
+ *\r
+ * @param uint16_t *address\r
+ * @param uint16_t value to store\r
+ * @return uint32_t successful / failed\r
+ *\r
+ * Exclusive STR command\r
+ */\r
+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);\r
+\r
+/**\r
+ * @brief STR Exclusive\r
+ *\r
+ * @param uint32_t *address\r
+ * @param uint32_t value to store\r
+ * @return uint32_t successful / failed\r
+ *\r
+ * Exclusive STR command\r
+ */\r
+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);\r
+\r
+\r
+\r
+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/\r
+/* GNU gcc specific functions */\r
+\r
+static __INLINE void __enable_irq() { __ASM volatile ("cpsie i"); }\r
+static __INLINE void __disable_irq() { __ASM volatile ("cpsid i"); }\r
+\r
+static __INLINE void __enable_fault_irq() { __ASM volatile ("cpsie f"); }\r
+static __INLINE void __disable_fault_irq() { __ASM volatile ("cpsid f"); }\r
+\r
+static __INLINE void __NOP() { __ASM volatile ("nop"); }\r
+static __INLINE void __WFI() { __ASM volatile ("wfi"); }\r
+static __INLINE void __WFE() { __ASM volatile ("wfe"); }\r
+static __INLINE void __SEV() { __ASM volatile ("sev"); }\r
+static __INLINE void __ISB() { __ASM volatile ("isb"); }\r
+static __INLINE void __DSB() { __ASM volatile ("dsb"); }\r
+static __INLINE void __DMB() { __ASM volatile ("dmb"); }\r
+static __INLINE void __CLREX() { __ASM volatile ("clrex"); }\r
+\r
+\r
+/**\r
+ * @brief Return the Process Stack Pointer\r
+ *\r
+ * @param none\r
+ * @return uint32_t ProcessStackPointer\r
+ *\r
+ * Return the actual process stack pointer\r
+ */\r
+extern uint32_t __get_PSP(void);\r
+\r
+/**\r
+ * @brief Set the Process Stack Pointer\r
+ *\r
+ * @param uint32_t Process Stack Pointer\r
+ * @return none\r
+ *\r
+ * Assign the value ProcessStackPointer to the MSP \r
+ * (process stack pointer) Cortex processor register\r
+ */\r
+extern void __set_PSP(uint32_t topOfProcStack);\r
+\r
+/**\r
+ * @brief Return the Main Stack Pointer\r
+ *\r
+ * @param none\r
+ * @return uint32_t Main Stack Pointer\r
+ *\r
+ * Return the current value of the MSP (main stack pointer)\r
+ * Cortex processor register\r
+ */\r
+extern uint32_t __get_MSP(void);\r
+\r
+/**\r
+ * @brief Set the Main Stack Pointer\r
+ *\r
+ * @param uint32_t Main Stack Pointer\r
+ * @return none\r
+ *\r
+ * Assign the value mainStackPointer to the MSP \r
+ * (main stack pointer) Cortex processor register\r
+ */\r
+extern void __set_MSP(uint32_t topOfMainStack);\r
+\r
+/**\r
+ * @brief Return the Base Priority value\r
+ *\r
+ * @param none\r
+ * @return uint32_t BasePriority\r
+ *\r
+ * Return the content of the base priority register\r
+ */\r
+extern uint32_t __get_BASEPRI(void);\r
+\r
+/**\r
+ * @brief Set the Base Priority value\r
+ *\r
+ * @param uint32_t BasePriority\r
+ * @return none\r
+ *\r
+ * Set the base priority register\r
+ */\r
+extern void __set_BASEPRI(uint32_t basePri);\r
+\r
+/**\r
+ * @brief Return the Priority Mask value\r
+ *\r
+ * @param none\r
+ * @return uint32_t PriMask\r
+ *\r
+ * Return the state of the priority mask bit from the priority mask\r
+ * register\r
+ */\r
+extern uint32_t __get_PRIMASK(void);\r
+\r
+/**\r
+ * @brief Set the Priority Mask value\r
+ *\r
+ * @param uint32_t PriMask\r
+ * @return none\r
+ *\r
+ * Set the priority mask bit in the priority mask register\r
+ */\r
+extern void __set_PRIMASK(uint32_t priMask);\r
+\r
+/**\r
+ * @brief Return the Fault Mask value\r
+ *\r
+ * @param none\r
+ * @return uint32_t FaultMask\r
+ *\r
+ * Return the content of the fault mask register\r
+ */\r
+extern uint32_t __get_FAULTMASK(void);\r
+\r
+/**\r
+ * @brief Set the Fault Mask value\r
+ *\r
+ * @param uint32_t faultMask value\r
+ * @return none\r
+ *\r
+ * Set the fault mask register\r
+ */\r
+extern void __set_FAULTMASK(uint32_t faultMask);\r
+\r
+/**\r
+ * @brief Return the Control Register value\r
+* \r
+* @param none\r
+* @return uint32_t Control value\r
+ *\r
+ * Return the content of the control register\r
+ */\r
+extern uint32_t __get_CONTROL(void);\r
+\r
+/**\r
+ * @brief Set the Control Register value\r
+ *\r
+ * @param uint32_t Control value\r
+ * @return none\r
+ *\r
+ * Set the control register\r
+ */\r
+extern void __set_CONTROL(uint32_t control);\r
+\r
+/**\r
+ * @brief Reverse byte order in integer value\r
+ *\r
+ * @param uint32_t value to reverse\r
+ * @return uint32_t reversed value\r
+ *\r
+ * Reverse byte order in integer value\r
+ */\r
+extern uint32_t __REV(uint32_t value);\r
+\r
+/**\r
+ * @brief Reverse byte order in unsigned short value\r
+ *\r
+ * @param uint16_t value to reverse\r
+ * @return uint32_t reversed value\r
+ *\r
+ * Reverse byte order in unsigned short value\r
+ */\r
+extern uint32_t __REV16(uint16_t value);\r
+\r
+/*\r
+ * Reverse byte order in signed short value with sign extension to integer\r
+ *\r
+ * @param int16_t value to reverse\r
+ * @return int32_t reversed value\r
+ *\r
+ * @brief Reverse byte order in signed short value with sign extension to integer\r
+ */\r
+extern int32_t __REVSH(int16_t value);\r
+\r
+/**\r
+ * @brief Reverse bit order of value\r
+ *\r
+ * @param uint32_t value to reverse\r
+ * @return uint32_t reversed value\r
+ *\r
+ * Reverse bit order of value\r
+ */\r
+extern uint32_t __RBIT(uint32_t value);\r
+\r
+/**\r
+ * @brief LDR Exclusive\r
+ *\r
+ * @param uint8_t* address\r
+ * @return uint8_t value of (*address)\r
+ *\r
+ * Exclusive LDR command\r
+ */\r
+extern uint8_t __LDREXB(uint8_t *addr);\r
+\r
+/**\r
+ * @brief LDR Exclusive\r
+ *\r
+ * @param uint16_t* address\r
+ * @return uint16_t value of (*address)\r
+ *\r
+ * Exclusive LDR command\r
+ */\r
+extern uint16_t __LDREXH(uint16_t *addr);\r
+\r
+/**\r
+ * @brief LDR Exclusive\r
+ *\r
+ * @param uint32_t* address\r
+ * @return uint32_t value of (*address)\r
+ *\r
+ * Exclusive LDR command\r
+ */\r
+extern uint32_t __LDREXW(uint32_t *addr);\r
+\r
+/**\r
+ * @brief STR Exclusive\r
+ *\r
+ * @param uint8_t *address\r
+ * @param uint8_t value to store\r
+ * @return uint32_t successful / failed\r
+ *\r
+ * Exclusive STR command\r
+ */\r
+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);\r
+\r
+/**\r
+ * @brief STR Exclusive\r
+ *\r
+ * @param uint16_t *address\r
+ * @param uint16_t value to store\r
+ * @return uint32_t successful / failed\r
+ *\r
+ * Exclusive STR command\r
+ */\r
+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);\r
+\r
+/**\r
+ * @brief STR Exclusive\r
+ *\r
+ * @param uint32_t *address\r
+ * @param uint32_t value to store\r
+ * @return uint32_t successful / failed\r
+ *\r
+ * Exclusive STR command\r
+ */\r
+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);\r
+\r
+\r
+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/\r
+/* TASKING carm specific functions */\r
+\r
+/*\r
+ * The CMSIS functions have been implemented as intrinsics in the compiler.\r
+ * Please use "carm -?i" to get an up to date list of all instrinsics,\r
+ * Including the CMSIS ones.\r
+ */\r
+\r
+#endif\r
+\r
+\r
+\r
+/* ########################## NVIC functions #################################### */\r
+\r
+\r
+/**\r
+ * @brief Set the Priority Grouping in NVIC Interrupt Controller\r
+ *\r
+ * @param uint32_t priority_grouping is priority grouping field\r
+ * @return none \r
+ *\r
+ * Set the priority grouping field using the required unlock sequence.\r
+ * The parameter priority_grouping is assigned to the field \r
+ * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used.\r
+ * In case of a conflict between priority grouping and available\r
+ * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.\r
+ */\r
+static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)\r
+{\r
+ uint32_t reg_value;\r
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */\r
+ \r
+ reg_value = SCB->AIRCR; /* read old register configuration */\r
+ reg_value &= ~((0xFFFFU << 16) | (0x0F << 8)); /* clear bits to change */\r
+ reg_value = ((reg_value | NVIC_AIRCR_VECTKEY | (PriorityGroupTmp << 8))); /* Insert write key and priorty group */\r
+ SCB->AIRCR = reg_value;\r
+}\r
+\r
+/**\r
+ * @brief Get the Priority Grouping from NVIC Interrupt Controller\r
+ *\r
+ * @param none\r
+ * @return uint32_t priority grouping field \r
+ *\r
+ * Get the priority grouping from NVIC Interrupt Controller.\r
+ * priority grouping is SCB->AIRCR [10:8] PRIGROUP field.\r
+ */\r
+static __INLINE uint32_t NVIC_GetPriorityGrouping(void)\r
+{\r
+ return ((SCB->AIRCR >> 8) & 0x07); /* read priority grouping field */\r
+}\r
+\r
+/**\r
+ * @brief Enable Interrupt in NVIC Interrupt Controller\r
+ *\r
+ * @param IRQn_Type IRQn specifies the interrupt number\r
+ * @return none \r
+ *\r
+ * Enable a device specific interupt in the NVIC interrupt controller.\r
+ * The interrupt number cannot be a negative value.\r
+ */\r
+static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)\r
+{\r
+ NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */\r
+}\r
+\r
+/**\r
+ * @brief Disable the interrupt line for external interrupt specified\r
+ * \r
+ * @param IRQn_Type IRQn is the positive number of the external interrupt\r
+ * @return none\r
+ * \r
+ * Disable a device specific interupt in the NVIC interrupt controller.\r
+ * The interrupt number cannot be a negative value.\r
+ */\r
+static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)\r
+{\r
+ NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */\r
+}\r
+\r
+/**\r
+ * @brief Read the interrupt pending bit for a device specific interrupt source\r
+ * \r
+ * @param IRQn_Type IRQn is the number of the device specifc interrupt\r
+ * @return uint32_t 1 if pending interrupt else 0\r
+ *\r
+ * Read the pending register in NVIC and return 1 if its status is pending, \r
+ * otherwise it returns 0\r
+ */\r
+static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)\r
+{\r
+ return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */\r
+}\r
+\r
+/**\r
+ * @brief Set the pending bit for an external interrupt\r
+ * \r
+ * @param IRQn_Type IRQn is the Number of the interrupt\r
+ * @return none\r
+ *\r
+ * Set the pending bit for the specified interrupt.\r
+ * The interrupt number cannot be a negative value.\r
+ */\r
+static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)\r
+{\r
+ NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */\r
+}\r
+\r
+/**\r
+ * @brief Clear the pending bit for an external interrupt\r
+ *\r
+ * @param IRQn_Type IRQn is the Number of the interrupt\r
+ * @return none\r
+ *\r
+ * Clear the pending bit for the specified interrupt. \r
+ * The interrupt number cannot be a negative value.\r
+ */\r
+static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)\r
+{\r
+ NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */\r
+}\r
+\r
+/**\r
+ * @brief Read the active bit for an external interrupt\r
+ *\r
+ * @param IRQn_Type IRQn is the Number of the interrupt\r
+ * @return uint32_t 1 if active else 0\r
+ *\r
+ * Read the active register in NVIC and returns 1 if its status is active, \r
+ * otherwise it returns 0.\r
+ */\r
+static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)\r
+{\r
+ return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */\r
+}\r
+\r
+/**\r
+ * @brief Set the priority for an interrupt\r
+ *\r
+ * @param IRQn_Type IRQn is the Number of the interrupt\r
+ * @param priority is the priority for the interrupt\r
+ * @return none\r
+ *\r
+ * Set the priority for the specified interrupt. The interrupt \r
+ * number can be positive to specify an external (device specific) \r
+ * interrupt, or negative to specify an internal (core) interrupt. \n\r
+ *\r
+ * Note: The priority cannot be set for every core interrupt.\r
+ */\r
+static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)\r
+{\r
+ if(IRQn < 0) {\r
+ SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */\r
+ else {\r
+ NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */\r
+}\r
+\r
+/**\r
+ * @brief Read the priority for an interrupt\r
+ *\r
+ * @param IRQn_Type IRQn is the Number of the interrupt\r
+ * @return uint32_t priority is the priority for the interrupt\r
+ *\r
+ * Read the priority for the specified interrupt. The interrupt \r
+ * number can be positive to specify an external (device specific) \r
+ * interrupt, or negative to specify an internal (core) interrupt.\r
+ *\r
+ * The returned priority value is automatically aligned to the implemented\r
+ * priority bits of the microcontroller.\r
+ *\r
+ * Note: The priority cannot be set for every core interrupt.\r
+ */\r
+static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)\r
+{\r
+\r
+ if(IRQn < 0) {\r
+ return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M3 system interrupts */\r
+ else {\r
+ return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */\r
+}\r
+\r
+\r
+/**\r
+ * @brief Encode the priority for an interrupt\r
+ *\r
+ * @param uint32_t PriorityGroup is the used priority group\r
+ * @param uint32_t PreemptPriority is the preemptive priority value (starting from 0)\r
+ * @param uint32_t SubPriority is the sub priority value (starting from 0)\r
+ * @return uint32_t the priority for the interrupt\r
+ *\r
+ * Encode the priority for an interrupt with the given priority group,\r
+ * preemptive priority value and sub priority value.\r
+ * In case of a conflict between priority grouping and available\r
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.\r
+ *\r
+ * The returned priority value can be used for NVIC_SetPriority(...) function\r
+ */\r
+static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)\r
+{\r
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */\r
+ uint32_t PreemptPriorityBits;\r
+ uint32_t SubPriorityBits;\r
+\r
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;\r
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;\r
+ \r
+ return (\r
+ ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |\r
+ ((SubPriority & ((1 << (SubPriorityBits )) - 1)))\r
+ );\r
+}\r
+\r
+\r
+/**\r
+ * @brief Decode the priority of an interrupt\r
+ *\r
+ * @param uint32_t Priority the priority for the interrupt\r
+ * @param uint32_t PrioGroup is the used priority group\r
+ * @param uint32_t* pPreemptPrio is the preemptive priority value (starting from 0)\r
+ * @param uint32_t* pSubPrio is the sub priority value (starting from 0)\r
+ * @return none\r
+ *\r
+ * Decode an interrupt priority value with the given priority group to \r
+ * preemptive priority value and sub priority value.\r
+ * In case of a conflict between priority grouping and available\r
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.\r
+ *\r
+ * The priority value can be retrieved with NVIC_GetPriority(...) function\r
+ */\r
+static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)\r
+{\r
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */\r
+ uint32_t PreemptPriorityBits;\r
+ uint32_t SubPriorityBits;\r
+\r
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;\r
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;\r
+ \r
+ *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);\r
+ *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1);\r
+}\r
+\r
+\r
+\r
+/* ################################## SysTick function ############################################ */\r
+\r
+#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)\r
+\r
+/* SysTick constants */\r
+#define SYSTICK_ENABLE 0 /* Config-Bit to start or stop the SysTick Timer */\r
+#define SYSTICK_TICKINT 1 /* Config-Bit to enable or disable the SysTick interrupt */\r
+#define SYSTICK_CLKSOURCE 2 /* Clocksource has the offset 2 in SysTick Control and Status Register */\r
+#define SYSTICK_MAXCOUNT ((1<<24) -1) /* SysTick MaxCount */\r
+\r
+/**\r
+ * @brief Initialize and start the SysTick counter and its interrupt.\r
+ *\r
+ * @param uint32_t ticks is the number of ticks between two interrupts\r
+ * @return none\r
+ *\r
+ * Initialise the system tick timer and its interrupt and start the\r
+ * system tick timer / counter in free running mode to generate \r
+ * periodical interrupts.\r
+ */\r
+static __INLINE uint32_t SysTick_Config(uint32_t ticks)\r
+{ \r
+ if (ticks > SYSTICK_MAXCOUNT) return (1); /* Reload value impossible */\r
+\r
+ SysTick->LOAD = (ticks & SYSTICK_MAXCOUNT) - 1; /* set reload register */\r
+ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */\r
+ SysTick->VAL = (0x00); /* Load the SysTick Counter Value */\r
+ SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<<SYSTICK_ENABLE) | (1<<SYSTICK_TICKINT); /* Enable SysTick IRQ and SysTick Timer */\r
+ return (0); /* Function successful */\r
+}\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+/* ################################## Reset function ############################################ */\r
+\r
+/**\r
+ * @brief Initiate a system reset request.\r
+ *\r
+ * @param none\r
+ * @return none\r
+ *\r
+ * Initialize a system reset request to reset the MCU\r
+ */\r
+static __INLINE void NVIC_SystemReset(void)\r
+{\r
+ SCB->AIRCR = (NVIC_AIRCR_VECTKEY | (SCB->AIRCR & (0x700)) | (1<<NVIC_SYSRESETREQ)); /* Keep priority group unchanged */\r
+ __DSB(); /* Ensure completion of memory access */ \r
+ while(1); /* wait until reset */\r
+}\r
+\r
+\r
+/* ################################## Debug Output function ############################################ */\r
+\r
+\r
+/**\r
+ * @brief Outputs a character via the ITM channel 0\r
+ *\r
+ * @param uint32_t character to output\r
+ * @return uint32_t input character\r
+ *\r
+ * The function outputs a character via the ITM channel 0. \r
+ * The function returns when no debugger is connected that has booked the output. \r
+ * It is blocking when a debugger is connected, but the previous character send is not transmitted. \r
+ */\r
+static __INLINE uint32_t ITM_SendChar (uint32_t ch)\r
+{\r
+ if (ch == '\n') ITM_SendChar('\r');\r
+ \r
+ if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA) &&\r
+ (ITM->TCR & ITM_TCR_ITMENA) &&\r
+ (ITM->TER & (1UL << 0)) ) \r
+ {\r
+ while (ITM->PORT[0].u32 == 0);\r
+ ITM->PORT[0].u8 = (uint8_t) ch;\r
+ } \r
+ return (ch);\r
+}\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* __CM3_CORE_H__ */\r
+\r
+/*lint -restore */\r
--- /dev/null
+<!DOCTYPE Linker_Placement_File>
+<Root name="Flash Section Placement">
+ <MemorySegment name="FLASH">
+ <ProgramSection load="Yes" inputsections="*(.vectors .vectors.*)" name=".vectors"/>
+ <ProgramSection alignment="4" load="Yes" inputsections="*(.init .init.*)" name=".init"/>
+ <ProgramSection alignment="4" load="Yes" inputsections="*(.text .text.* .glue_7t .glue_7 .gnu.linkonce.t.* .gcc_except_table)" name=".text"/>
+ <ProgramSection alignment="4" load="Yes" inputsections="KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors))" name=".dtors"/>
+ <ProgramSection alignment="4" load="Yes" inputsections="KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors))" name=".ctors"/>
+ <ProgramSection alignment="4" load="Yes" inputsections="*(.rodata .rodata.* .gnu.linkonce.r.*)" name=".rodata"/>
+ <ProgramSection alignment="4" load="Yes" runin=".fast_run" inputsections="*(.fast .fast.*)" name=".fast"/>
+ <ProgramSection alignment="4" load="Yes" runin=".data_run" inputsections="*(.data .data.* .gnu.linkonce.d.*)" name=".data"/>
+ </MemorySegment>
+ <MemorySegment name="RAM">
+ <ProgramSection alignment="4" load="No" name=".fast_run"/>
+ <ProgramSection alignment="4" load="No" name=".data_run"/>
+ <ProgramSection alignment="4" load="No" inputsections="*(.bss .bss.* .gnu.linkonce.b.*) *(COMMON)" name=".bss"/>
+ <ProgramSection alignment="4" load="No" inputsections="*(.non_init .non_init.*)" name=".non_init"/>
+ <ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap"/>
+ <ProgramSection alignment="4" size="__STACKSIZE__" load="No" name=".stack"/>
+ <ProgramSection alignment="4" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process"/>
+ </MemorySegment>
+ <MemorySegment name="AHBSRAM0">
+ <ProgramSection alignment="4" load="No" name=".ethram"/>
+ </MemorySegment>
+ <MemorySegment name="AHBSRAM1">
+ <ProgramSection alignment="4" load="No" name=".usbram"/>
+ </MemorySegment>
+ <MemorySegment name="FLASH2">
+ <ProgramSection alignment="4" load="Yes" inputsections="*(.text2 .text2.*)" name=".text2"/>
+ <ProgramSection alignment="4" load="Yes" inputsections="*(.rodata2 .rodata2.*)" name=".rodata2"/>
+ <ProgramSection alignment="4" load="Yes" runin=".data2_run" inputsections="*(.data2 .data2.*)" name=".data2"/>
+ </MemorySegment>
+ <MemorySegment name="RAM2">
+ <ProgramSection alignment="4" load="No" name=".data2_run"/>
+ <ProgramSection alignment="4" load="No" inputsections="*(.bss2 .bss2.*" name=".bss2"/>
+ </MemorySegment>
+</Root>
--- /dev/null
+/*\r
+ FreeRTOS V6.0.2 - Copyright (C) 2010 Real Time Engineers Ltd.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * If you are: *\r
+ * *\r
+ * + New to FreeRTOS, *\r
+ * + Wanting to learn FreeRTOS or multitasking in general quickly *\r
+ * + Looking for basic training, *\r
+ * + Wanting to improve your FreeRTOS skills and productivity *\r
+ * *\r
+ * then take a look at the FreeRTOS eBook *\r
+ * *\r
+ * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ * A pdf reference manual is also available. Both are usually delivered *\r
+ * to your inbox within 20 minutes to two hours when purchased between 8am *\r
+ * and 8pm GMT (although please allow up to 24 hours in case of *\r
+ * exceptional circumstances). Thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ ***NOTE*** The exception to the GPL is included to allow you to distribute\r
+ a combined work that includes FreeRTOS without being obliged to provide the\r
+ source code for proprietary components outside of the FreeRTOS kernel.\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public \r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it \r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained \r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+\r
+/*\r
+ * Creates all the demo application tasks, then starts the scheduler. The WEB\r
+ * documentation provides more details of the standard demo application tasks\r
+ * (which just exist to test the kernel port and provide an example of how to use\r
+ * each FreeRTOS API function).\r
+ *\r
+ * In addition to the standard demo tasks, the following tasks and tests are\r
+ * defined and/or created within this file:\r
+ *\r
+ * "Check" hook - This only executes fully every five seconds from the tick\r
+ * hook. Its main function is to check that all the standard demo tasks are\r
+ * still operational. The status can be viewed using on the Task Stats page\r
+ * served by the WEB server.\r
+ *\r
+ * "uIP" task - This is the task that handles the uIP stack. All TCP/IP\r
+ * processing is performed in this task.\r
+ * \r
+ * "USB" task - Enumerates the USB device as a CDC class, then echoes back all\r
+ * received characters with a configurable offset (for example, if the offset\r
+ * is 1 and 'A' is received then 'B' will be sent back). A dumb terminal such\r
+ * as Hyperterminal can be used to talk to the USB task.\r
+ */\r
+\r
+/* Scheduler includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Demo app includes. */\r
+#include "BlockQ.h"\r
+#include "integer.h"\r
+#include "blocktim.h"\r
+#include "flash.h"\r
+#include "partest.h"\r
+#include "semtest.h"\r
+#include "PollQ.h"\r
+#include "GenQTest.h"\r
+#include "QPeek.h"\r
+#include "recmutex.h"\r
+\r
+/* File system includes. */\r
+#include "diskio.h"\r
+#include "ff.h"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The time between cycles of the 'check' functionality (defined within the\r
+tick hook). */\r
+#define mainCHECK_DELAY ( ( portTickType ) 5000 / portTICK_RATE_MS )\r
+\r
+/* Task priorities. */\r
+#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
+#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#define mainUIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )\r
+#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
+#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
+#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+\r
+/* The WEB server has a larger stack as it utilises stack hungry string\r
+handling library calls. */\r
+#define mainBASIC_WEB_STACK_SIZE ( configMINIMAL_STACK_SIZE * 4 )\r
+\r
+/* The message displayed by the WEB server when all tasks are executing\r
+without an error being reported. */\r
+#define mainPASS_STATUS_MESSAGE "All tasks are executing without error."\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Configure the hardware for the demo.\r
+ */\r
+static void prvSetupHardware( void );\r
+\r
+/*\r
+ * The task that handles the uIP stack. All TCP/IP processing is performed in\r
+ * this task.\r
+ */\r
+extern void vuIP_Task( void *pvParameters );\r
+\r
+/*\r
+ * The task that handles the USB stack.\r
+ */\r
+extern void vUSBTask( void *pvParameters );\r
+\r
+/*\r
+ * Simply returns the current status message for display on served WEB pages.\r
+ */\r
+char *pcGetTaskStatusMessage( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Holds the status message displayed by the WEB server. */\r
+static char *pcStatusMessage = mainPASS_STATUS_MESSAGE;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+int main( void )\r
+{\r
+ /* Configure the hardware for use by this demo. */\r
+ prvSetupHardware();\r
+\r
+ /* Start the standard demo tasks. These are just here to exercise the\r
+ kernel port and provide examples of how the FreeRTOS API can be used. */\r
+ vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );\r
+ vCreateBlockTimeTasks();\r
+ vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
+ vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
+ vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );\r
+ vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );\r
+ vStartQueuePeekTasks();\r
+ vStartRecursiveMutexTasks();\r
+ vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );\r
+\r
+ /* Create the USB task. */\r
+ xTaskCreate( vUSBTask, ( signed char * ) "USB", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );\r
+ \r
+ /* Create the uIP task. The WEB server runs in this task. */\r
+ xTaskCreate( vuIP_Task, ( signed char * ) "uIP", mainBASIC_WEB_STACK_SIZE, ( void * ) NULL, mainUIP_TASK_PRIORITY, NULL );\r
+\r
+ /* Start the scheduler. */\r
+ vTaskStartScheduler();\r
+\r
+ /* Will only get here if there was insufficient memory to create the idle\r
+ task. The idle task is created within vTaskStartScheduler(). */\r
+ for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationTickHook( void )\r
+{\r
+static unsigned long ulTicksSinceLastDisplay = 0;\r
+\r
+ /* Called from every tick interrupt as described in the comments at the top\r
+ of this file.\r
+\r
+ Have enough ticks passed to make it time to perform our health status\r
+ check again? */\r
+ ulTicksSinceLastDisplay++;\r
+ if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )\r
+ {\r
+ /* Reset the counter so these checks run again in mainCHECK_DELAY\r
+ ticks time. */\r
+ ulTicksSinceLastDisplay = 0;\r
+\r
+ /* Has an error been found in any task? */\r
+ if( xAreGenericQueueTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Generic Queue test/demo.";\r
+ }\r
+ else if( xAreQueuePeekTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Peek Queue test/demo.";\r
+ }\r
+ else if( xAreBlockingQueuesStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Block Queue test/demo.";\r
+ }\r
+ else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Block Time test/demo.";\r
+ }\r
+ else if( xAreSemaphoreTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Semaphore test/demo.";\r
+ }\r
+ else if( xArePollingQueuesStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Poll Queue test/demo.";\r
+ }\r
+ else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Int Math test/demo.";\r
+ }\r
+ else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Mutex test/demo.";\r
+ }\r
+ }\r
+\r
+ disk_timerproc();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+char *pcGetTaskStatusMessage( void )\r
+{\r
+ /* Not bothered about a critical section here. */\r
+ return pcStatusMessage;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void prvSetupHardware( void )\r
+{\r
+ /* Disable peripherals power. */\r
+ SC->PCONP = 0;\r
+\r
+ /* Enable GPIO power. */\r
+ SC->PCONP = PCONP_PCGPIO;\r
+\r
+ /* Disable TPIU. */\r
+ PINCON->PINSEL10 = 0;\r
+\r
+ /* Setup the peripheral bus to be the same as the PLL output (64 MHz). */\r
+ SC->PCLKSEL0 = 0x05555555;\r
+\r
+ /* Configure the LEDs. */\r
+ vParTestInitialise();\r
+\r
+ /* Configure the SPI for communicating with the SD card. */\r
+ disk_init_spi();\r
+\r
+{\r
+FATFS fs;\r
+FIL f;\r
+static char c[ 2048 ];\r
+UINT BytesRead;\r
+\r
+ f_mount( 0, &fs );\r
+ f_open( &f, "/test.htm", FA_READ );\r
+ f_read( &f, c, 2048, &BytesRead );\r
+ __asm volatile( "NOP" );\r
+}\r
+\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )\r
+{\r
+ /* This function will get called if a task overflows its stack. */\r
+\r
+ ( void ) pxTask;\r
+ ( void ) pcTaskName;\r
+\r
+ for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vConfigureTimerForRunTimeStats( void )\r
+{\r
+const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;\r
+\r
+ /* This function configures a timer that is used as the time base when\r
+ collecting run time statistical information - basically the percentage\r
+ of CPU time that each task is utilising. It is called automatically when\r
+ the scheduler is started (assuming configGENERATE_RUN_TIME_STATS is set\r
+ to 1). */\r
+\r
+ /* Power up and feed the timer. */\r
+ SC->PCONP |= 0x02UL;\r
+ SC->PCLKSEL0 = (SC->PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);\r
+\r
+ /* Reset Timer 0 */\r
+ TIM0->TCR = TCR_COUNT_RESET;\r
+\r
+ /* Just count up. */\r
+ TIM0->CTCR = CTCR_CTM_TIMER;\r
+\r
+ /* Prescale to a frequency that is good enough to get a decent resolution,\r
+ but not too fast so as to overflow all the time. */\r
+ TIM0->PR = ( configCPU_CLOCK_HZ / 10000UL ) - 1UL;\r
+\r
+ /* Start the counter. */\r
+ TIM0->TCR = TCR_COUNT_ENABLE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V6.0.2 - Copyright (C) 2010 Real Time Engineers Ltd.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * If you are: *\r
+ * *\r
+ * + New to FreeRTOS, *\r
+ * + Wanting to learn FreeRTOS or multitasking in general quickly *\r
+ * + Looking for basic training, *\r
+ * + Wanting to improve your FreeRTOS skills and productivity *\r
+ * *\r
+ * then take a look at the FreeRTOS eBook *\r
+ * *\r
+ * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ * A pdf reference manual is also available. Both are usually delivered *\r
+ * to your inbox within 20 minutes to two hours when purchased between 8am *\r
+ * and 8pm GMT (although please allow up to 24 hours in case of *\r
+ * exceptional circumstances). Thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ ***NOTE*** The exception to the GPL is included to allow you to distribute\r
+ a combined work that includes FreeRTOS without being obliged to provide the\r
+ source code for proprietary components outside of the FreeRTOS kernel.\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public \r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it \r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained \r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+\r
+/*\r
+ * Creates all the demo application tasks, then starts the scheduler. The WEB\r
+ * documentation provides more details of the standard demo application tasks\r
+ * (which just exist to test the kernel port and provide an example of how to use\r
+ * each FreeRTOS API function).\r
+ *\r
+ * In addition to the standard demo tasks, the following tasks and tests are\r
+ * defined and/or created within this file:\r
+ *\r
+ * "Check" hook - This only executes fully every five seconds from the tick\r
+ * hook. Its main function is to check that all the standard demo tasks are\r
+ * still operational. The status can be viewed using on the Task Stats page\r
+ * served by the WEB server.\r
+ *\r
+ * "uIP" task - This is the task that handles the uIP stack. All TCP/IP\r
+ * processing is performed in this task.\r
+ * \r
+ * "USB" task - Enumerates the USB device as a CDC class, then echoes back all\r
+ * received characters with a configurable offset (for example, if the offset\r
+ * is 1 and 'A' is received then 'B' will be sent back). A dumb terminal such\r
+ * as Hyperterminal can be used to talk to the USB task.\r
+ */\r
+\r
+/* Scheduler includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Demo app includes. */\r
+#include "BlockQ.h"\r
+#include "integer.h"\r
+#include "blocktim.h"\r
+#include "flash.h"\r
+#include "partest.h"\r
+#include "semtest.h"\r
+#include "PollQ.h"\r
+#include "GenQTest.h"\r
+#include "QPeek.h"\r
+#include "recmutex.h"\r
+\r
+/* File system includes. */\r
+#include "diskio.h"\r
+#include "ff.h"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The time between cycles of the 'check' functionality (defined within the\r
+tick hook). */\r
+#define mainCHECK_DELAY ( ( portTickType ) 5000 / portTICK_RATE_MS )\r
+\r
+/* Task priorities. */\r
+#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
+#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#define mainUIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )\r
+#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
+#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
+#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+\r
+/* The WEB server has a larger stack as it utilises stack hungry string\r
+handling library calls. */\r
+#define mainBASIC_WEB_STACK_SIZE ( configMINIMAL_STACK_SIZE * 4 )\r
+\r
+/* The message displayed by the WEB server when all tasks are executing\r
+without an error being reported. */\r
+#define mainPASS_STATUS_MESSAGE "All tasks are executing without error."\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Configure the hardware for the demo.\r
+ */\r
+static void prvSetupHardware( void );\r
+\r
+/*\r
+ * The task that handles the uIP stack. All TCP/IP processing is performed in\r
+ * this task.\r
+ */\r
+extern void vuIP_Task( void *pvParameters );\r
+\r
+/*\r
+ * The task that handles the USB stack.\r
+ */\r
+extern void vUSBTask( void *pvParameters );\r
+\r
+/*\r
+ * Simply returns the current status message for display on served WEB pages.\r
+ */\r
+char *pcGetTaskStatusMessage( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Holds the status message displayed by the WEB server. */\r
+static char *pcStatusMessage = mainPASS_STATUS_MESSAGE;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+int main( void )\r
+{\r
+ /* Configure the hardware for use by this demo. */\r
+ prvSetupHardware();\r
+\r
+ /* Start the standard demo tasks. These are just here to exercise the\r
+ kernel port and provide examples of how the FreeRTOS API can be used. */\r
+ vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );\r
+ vCreateBlockTimeTasks();\r
+ vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
+ vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
+ vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );\r
+ vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );\r
+ vStartQueuePeekTasks();\r
+ vStartRecursiveMutexTasks();\r
+ vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );\r
+\r
+ /* Create the USB task. */\r
+ xTaskCreate( vUSBTask, ( signed char * ) "USB", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );\r
+ \r
+ /* Create the uIP task. The WEB server runs in this task. */\r
+ xTaskCreate( vuIP_Task, ( signed char * ) "uIP", mainBASIC_WEB_STACK_SIZE, ( void * ) NULL, mainUIP_TASK_PRIORITY, NULL );\r
+\r
+ /* Start the scheduler. */\r
+ vTaskStartScheduler();\r
+\r
+ /* Will only get here if there was insufficient memory to create the idle\r
+ task. The idle task is created within vTaskStartScheduler(). */\r
+ for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationTickHook( void )\r
+{\r
+static unsigned long ulTicksSinceLastDisplay = 0;\r
+\r
+ /* Called from every tick interrupt as described in the comments at the top\r
+ of this file.\r
+\r
+ Have enough ticks passed to make it time to perform our health status\r
+ check again? */\r
+ ulTicksSinceLastDisplay++;\r
+ if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )\r
+ {\r
+ /* Reset the counter so these checks run again in mainCHECK_DELAY\r
+ ticks time. */\r
+ ulTicksSinceLastDisplay = 0;\r
+\r
+ /* Has an error been found in any task? */\r
+ if( xAreGenericQueueTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Generic Queue test/demo.";\r
+ }\r
+ else if( xAreQueuePeekTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Peek Queue test/demo.";\r
+ }\r
+ else if( xAreBlockingQueuesStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Block Queue test/demo.";\r
+ }\r
+ else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Block Time test/demo.";\r
+ }\r
+ else if( xAreSemaphoreTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Semaphore test/demo.";\r
+ }\r
+ else if( xArePollingQueuesStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Poll Queue test/demo.";\r
+ }\r
+ else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Int Math test/demo.";\r
+ }\r
+ else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "An error has been detected in the Mutex test/demo.";\r
+ }\r
+ }\r
+\r
+ disk_timerproc();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+char *pcGetTaskStatusMessage( void )\r
+{\r
+ /* Not bothered about a critical section here. */\r
+ return pcStatusMessage;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void prvSetupHardware( void )\r
+{\r
+ /* Disable peripherals power. */\r
+ SC->PCONP = 0;\r
+\r
+ /* Enable GPIO power. */\r
+ SC->PCONP = PCONP_PCGPIO;\r
+\r
+ /* Disable TPIU. */\r
+ PINCON->PINSEL10 = 0;\r
+\r
+ /* Setup the peripheral bus to be the same as the PLL output (64 MHz). */\r
+ SC->PCLKSEL0 = 0x05555555;\r
+\r
+ /* Configure the LEDs. */\r
+ vParTestInitialise();\r
+\r
+ /* Configure the SPI for communicating with the SD card. */\r
+ disk_init_spi();\r
+\r
+{\r
+FATFS fs;\r
+FIL f;\r
+static char c[ 2048 ];\r
+UINT BytesRead;\r
+\r
+ f_mount( 0, &fs );\r
+ f_open( &f, "/test.htm", FA_READ );\r
+ f_read( &f, c, 2048, &BytesRead );\r
+}\r
+\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )\r
+{\r
+ /* This function will get called if a task overflows its stack. */\r
+\r
+ ( void ) pxTask;\r
+ ( void ) pcTaskName;\r
+\r
+ for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vConfigureTimerForRunTimeStats( void )\r
+{\r
+const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;\r
+\r
+ /* This function configures a timer that is used as the time base when\r
+ collecting run time statistical information - basically the percentage\r
+ of CPU time that each task is utilising. It is called automatically when\r
+ the scheduler is started (assuming configGENERATE_RUN_TIME_STATS is set\r
+ to 1). */\r
+\r
+ /* Power up and feed the timer. */\r
+ SC->PCONP |= 0x02UL;\r
+ SC->PCLKSEL0 = (SC->PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);\r
+\r
+ /* Reset Timer 0 */\r
+ TIM0->TCR = TCR_COUNT_RESET;\r
+\r
+ /* Just count up. */\r
+ TIM0->CTCR = CTCR_CTM_TIMER;\r
+\r
+ /* Prescale to a frequency that is good enough to get a decent resolution,\r
+ but not too fast so as to overflow all the time. */\r
+ TIM0->PR = ( configCPU_CLOCK_HZ / 10000UL ) - 1UL;\r
+\r
+ /* Start the counter. */\r
+ TIM0->TCR = TCR_COUNT_ENABLE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
--- /dev/null
+/*\r
+ Copyright 2001, 2002 Georges Menie (www.menie.org)\r
+ stdarg version contributed by Christian Ettinger\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU Lesser General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU Lesser General Public License for more details.\r
+\r
+ You should have received a copy of the GNU Lesser General Public License\r
+ along with this program; if not, write to the Free Software\r
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+*/\r
+\r
+/*\r
+ putchar is the only external dependency for this file,\r
+ if you have a working putchar, leave it commented out.\r
+ If not, uncomment the define below and\r
+ replace outbyte(c) by your own function call.\r
+\r
+*/\r
+\r
+#define putchar(c) c\r
+\r
+#include <stdarg.h>\r
+\r
+static void printchar(char **str, int c)\r
+{\r
+ //extern int putchar(int c);\r
+ \r
+ if (str) {\r
+ **str = (char)c;\r
+ ++(*str);\r
+ }\r
+ else\r
+ { \r
+ (void)putchar(c);\r
+ }\r
+}\r
+\r
+#define PAD_RIGHT 1\r
+#define PAD_ZERO 2\r
+\r
+static int prints(char **out, const char *string, int width, int pad)\r
+{\r
+ register int pc = 0, padchar = ' ';\r
+\r
+ if (width > 0) {\r
+ register int len = 0;\r
+ register const char *ptr;\r
+ for (ptr = string; *ptr; ++ptr) ++len;\r
+ if (len >= width) width = 0;\r
+ else width -= len;\r
+ if (pad & PAD_ZERO) padchar = '0';\r
+ }\r
+ if (!(pad & PAD_RIGHT)) {\r
+ for ( ; width > 0; --width) {\r
+ printchar (out, padchar);\r
+ ++pc;\r
+ }\r
+ }\r
+ for ( ; *string ; ++string) {\r
+ printchar (out, *string);\r
+ ++pc;\r
+ }\r
+ for ( ; width > 0; --width) {\r
+ printchar (out, padchar);\r
+ ++pc;\r
+ }\r
+\r
+ return pc;\r
+}\r
+\r
+/* the following should be enough for 32 bit int */\r
+#define PRINT_BUF_LEN 12\r
+\r
+static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)\r
+{\r
+ char print_buf[PRINT_BUF_LEN];\r
+ register char *s;\r
+ register int t, neg = 0, pc = 0;\r
+ register unsigned int u = (unsigned int)i;\r
+\r
+ if (i == 0) {\r
+ print_buf[0] = '0';\r
+ print_buf[1] = '\0';\r
+ return prints (out, print_buf, width, pad);\r
+ }\r
+\r
+ if (sg && b == 10 && i < 0) {\r
+ neg = 1;\r
+ u = (unsigned int)-i;\r
+ }\r
+\r
+ s = print_buf + PRINT_BUF_LEN-1;\r
+ *s = '\0';\r
+\r
+ while (u) {\r
+ t = (unsigned int)u % b;\r
+ if( t >= 10 )\r
+ t += letbase - '0' - 10;\r
+ *--s = (char)(t + '0');\r
+ u /= b;\r
+ }\r
+\r
+ if (neg) {\r
+ if( width && (pad & PAD_ZERO) ) {\r
+ printchar (out, '-');\r
+ ++pc;\r
+ --width;\r
+ }\r
+ else {\r
+ *--s = '-';\r
+ }\r
+ }\r
+\r
+ return pc + prints (out, s, width, pad);\r
+}\r
+\r
+static int print( char **out, const char *format, va_list args )\r
+{\r
+ register int width, pad;\r
+ register int pc = 0;\r
+ char scr[2];\r
+\r
+ for (; *format != 0; ++format) {\r
+ if (*format == '%') {\r
+ ++format;\r
+ width = pad = 0;\r
+ if (*format == '\0') break;\r
+ if (*format == '%') goto out;\r
+ if (*format == '-') {\r
+ ++format;\r
+ pad = PAD_RIGHT;\r
+ }\r
+ while (*format == '0') {\r
+ ++format;\r
+ pad |= PAD_ZERO;\r
+ }\r
+ for ( ; *format >= '0' && *format <= '9'; ++format) {\r
+ width *= 10;\r
+ width += *format - '0';\r
+ }\r
+ if( *format == 's' ) {\r
+ register char *s = (char *)va_arg( args, int );\r
+ pc += prints (out, s?s:"(null)", width, pad);\r
+ continue;\r
+ }\r
+ if( *format == 'd' ) {\r
+ pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a');\r
+ continue;\r
+ }\r
+ if( *format == 'x' ) {\r
+ pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a');\r
+ continue;\r
+ }\r
+ if( *format == 'X' ) {\r
+ pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A');\r
+ continue;\r
+ }\r
+ if( *format == 'u' ) {\r
+ pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a');\r
+ continue;\r
+ }\r
+ if( *format == 'c' ) {\r
+ /* char are converted to int then pushed on the stack */\r
+ scr[0] = (char)va_arg( args, int );\r
+ scr[1] = '\0';\r
+ pc += prints (out, scr, width, pad);\r
+ continue;\r
+ }\r
+ }\r
+ else {\r
+ out:\r
+ printchar (out, *format);\r
+ ++pc;\r
+ }\r
+ }\r
+ if (out) **out = '\0';\r
+ va_end( args );\r
+ return pc;\r
+}\r
+\r
+int printf(const char *format, ...)\r
+{\r
+ va_list args;\r
+ \r
+ va_start( args, format );\r
+ return print( 0, format, args );\r
+}\r
+\r
+int sprintf(char *out, const char *format, ...)\r
+{\r
+ va_list args;\r
+ \r
+ va_start( args, format );\r
+ return print( &out, format, args );\r
+}\r
+\r
+\r
+int snprintf( char *buf, unsigned int count, const char *format, ... )\r
+{\r
+ va_list args;\r
+ \r
+ ( void ) count;\r
+ \r
+ va_start( args, format );\r
+ return print( &buf, format, args );\r
+}\r
+\r
+\r
+#ifdef TEST_PRINTF\r
+int main(void)\r
+{\r
+ char *ptr = "Hello world!";\r
+ char *np = 0;\r
+ int i = 5;\r
+ unsigned int bs = sizeof(int)*8;\r
+ int mi;\r
+ char buf[80];\r
+\r
+ mi = (1 << (bs-1)) + 1;\r
+ printf("%s\n", ptr);\r
+ printf("printf test\n");\r
+ printf("%s is null pointer\n", np);\r
+ printf("%d = 5\n", i);\r
+ printf("%d = - max int\n", mi);\r
+ printf("char %c = 'a'\n", 'a');\r
+ printf("hex %x = ff\n", 0xff);\r
+ printf("hex %02x = 00\n", 0);\r
+ printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);\r
+ printf("%d %s(s)%", 0, "message");\r
+ printf("\n");\r
+ printf("%d %s(s) with %%\n", 0, "message");\r
+ sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf);\r
+ sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf);\r
+ sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf);\r
+ sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf);\r
+ sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf);\r
+ sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf);\r
+ sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf);\r
+ sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf);\r
+\r
+ return 0;\r
+}\r
+\r
+/*\r
+ * if you compile this file with\r
+ * gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c\r
+ * you will get a normal warning:\r
+ * printf.c:214: warning: spurious trailing `%' in format\r
+ * this line is testing an invalid % at the end of the format string.\r
+ *\r
+ * this should display (on 32bit int machine) :\r
+ *\r
+ * Hello world!\r
+ * printf test\r
+ * (null) is null pointer\r
+ * 5 = 5\r
+ * -2147483647 = - max int\r
+ * char a = 'a'\r
+ * hex ff = ff\r
+ * hex 00 = 00\r
+ * signed -3 = unsigned 4294967293 = hex fffffffd\r
+ * 0 message(s)\r
+ * 0 message(s) with %\r
+ * justif: "left "\r
+ * justif: " right"\r
+ * 3: 0003 zero padded\r
+ * 3: 3 left justif.\r
+ * 3: 3 right justif.\r
+ * -3: -003 zero padded\r
+ * -3: -3 left justif.\r
+ * -3: -3 right justif.\r
+ */\r
+\r
+#endif\r
+\r
+\r
+/* To keep linker happy. */\r
+int write( int i, char* c, int n)\r
+{\r
+ (void)i;\r
+ (void)n;\r
+ (void)c;\r
+ return 0;\r
+}\r
+\r
--- /dev/null
+/******************************************************************************\r
+ * @file: system_LPC17xx.h\r
+ * @purpose: CMSIS Cortex-M3 Device Peripheral Access Layer Header File\r
+ * for the NXP LPC17xx Device Series \r
+ * @version: V1.0\r
+ * @date: 25. Nov. 2008\r
+ *----------------------------------------------------------------------------\r
+ *\r
+ * Copyright (C) 2008 ARM Limited. All rights reserved.\r
+ *\r
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M3 \r
+ * processor based microcontrollers. This file can be freely distributed \r
+ * within development tools that are supporting such ARM based processors. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
+ *\r
+ ******************************************************************************/\r
+\r
+\r
+#ifndef __SYSTEM_LPC17xx_H\r
+#define __SYSTEM_LPC17xx_H\r
+\r
+extern uint32_t SystemFrequency; /*!< System Clock Frequency (Core Clock) */\r
+\r
+\r
+/**\r
+ * Initialize the system\r
+ *\r
+ * @param none\r
+ * @return none\r
+ *\r
+ * @brief Setup the microcontroller system.\r
+ * Initialize the System and update the SystemFrequency variable.\r
+ */\r
+extern void SystemInit (void);\r
+#endif\r
--- /dev/null
+[Version]\r
+Signature="$Windows NT$"\r
+Class=Ports\r
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}\r
+Provider=%LINUX%\r
+DriverVer=08/17/2004,0.0.2.0\r
+; Copyright (C) 2004 Al Borchers (alborchers@steinerpoint.com)\r
+; released under GNU General Public License\r
+\r
+[Manufacturer]\r
+%LINUX%=GSerialDeviceList\r
+\r
+[GSerialDeviceList]\r
+%GSERIAL%=GSerialInstall, USB\VID_FFFF&PID_0005\r
+\r
+[DestinationDirs]\r
+DefaultDestDir=10,System32\Drivers\r
+\r
+[GSerialInstall]\r
+CopyFiles=GSerialCopyFiles\r
+AddReg=GSerialAddReg\r
+\r
+[GSerialCopyFiles]\r
+usbser.sys\r
+\r
+[GSerialAddReg]\r
+HKR,,DevLoader,,*ntkern\r
+HKR,,NTMPDriver,,usbser.sys\r
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"\r
+\r
+[GSerialInstall.Services]\r
+AddService = usbser,0x0002,GSerialService\r
+\r
+[GSerialService]\r
+DisplayName = %GSERIAL_DISPLAY_NAME%\r
+ServiceType = 1 ; SERVICE_KERNEL_DRIVER\r
+StartType = 3 ; SERVICE_DEMAND_START\r
+ErrorControl = 1 ; SERVICE_ERROR_NORMAL\r
+ServiceBinary = %10%\System32\Drivers\usbser.sys\r
+LoadOrderGroup = Base\r
+\r
+[Strings]\r
+LINUX = "Linux"\r
+GSERIAL = "USB CDC serial port emulation"\r
+GSERIAL_DISPLAY_NAME = "USB CDC serial port emulation"
\ No newline at end of file
--- /dev/null
+/*\r
+ * @file: EthDev.h\r
+ * @purpose: Ethernet Device Definitions\r
+ * @version: V1.10\r
+ * @date: 24. Feb. 2009\r
+ *----------------------------------------------------------------------------\r
+ *\r
+ * Copyright (C) 2009 ARM Limited. All rights reserved.\r
+ *\r
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M3\r
+ * processor based microcontrollers. This file can be freely distributed\r
+ * within development tools that are supporting such ARM based processors.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
+ *\r
+ */\r
+\r
+#ifndef _ETHDEV__H\r
+#define _ETHDEV__H\r
+\r
+#ifndef NULL\r
+ #define NULL 0\r
+#endif\r
+\r
+/*----------------------------------------------------------------------------\r
+ Ethernet Device Defines\r
+ *----------------------------------------------------------------------------*/\r
+#define EthDev_ADDR_SIZE 6 /*!< Ethernet Address size in bytes */\r
+#define EthDev_MTU_SIZE 1514 /*!< Maximum Transmission Unit */\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+ Ethernet Device Configuration and Control Command Defines\r
+ *----------------------------------------------------------------------------*/\r
+typedef enum {\r
+ EthDev_LINK_DOWN = 0, /*!< Ethernet link not established */\r
+ EthDev_LINK_UP = 1, /*!< Ethernet link established */\r
+} EthDev_LINK;\r
+\r
+typedef enum {\r
+ EthDev_SPEED_10M = 0, /*!< 10.0 Mbps link speed */\r
+ EthDev_SPEED_100M = 1, /*!< 100.0 Mbps link speed */\r
+ EthDev_SPEED_1000M = 2, /*!< 1.0 Gbps link speed */\r
+} EthDev_SPEED;\r
+\r
+typedef enum {\r
+ EthDev_DUPLEX_HALF = 0, /*!< Link half duplex */\r
+ EthDev_DUPLEX_FULL = 1, /*!< Link full duplex */\r
+} EthDev_DUPLEX;\r
+\r
+typedef enum {\r
+ EthDev_MODE_AUTO = 0,\r
+ EthDev_MODE_10M_FULL = 1,\r
+ EthDev_MODE_10M_HALF = 2,\r
+ EthDev_MODE_100M_FULL = 3,\r
+ EthDev_MODE_100M_HALF = 4,\r
+ EthDev_MODE_1000M_FULL = 5,\r
+ EthDev_MODE_1000M_HALF = 6,\r
+} EthDev_MODE;\r
+\r
+typedef struct {\r
+ EthDev_LINK Link : 1;\r
+ EthDev_DUPLEX Duplex : 1;\r
+ EthDev_SPEED Speed : 2;\r
+} EthDev_STATUS;\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+ Ethernet Device IO Block Structure\r
+ *----------------------------------------------------------------------------*/\r
+typedef struct {\r
+\r
+ /* Initialized by the user application before call to Init. */\r
+ EthDev_MODE Mode;\r
+ unsigned char HwAddr[EthDev_ADDR_SIZE];\r
+ void *(*RxFrame) (int size);\r
+ void (*RxFrameReady) (int size);\r
+\r
+ /* Initialized by Ethernet driver. */\r
+ int (*Init) (void);\r
+ int (*UnInit) (void);\r
+ int (*SetMCFilter)(int NumHwAddr, unsigned char *pHwAddr);\r
+ int (*TxFrame) (void *pData, int size);\r
+ void (*Lock) (void);\r
+ void (*UnLock) (void);\r
+ EthDev_STATUS (*LinkChk) (void);\r
+} EthDev_IOB;\r
+\r
+\r
+/*\r
+ * Look for received data. If data is found then uip_buf is assigned to the\r
+ * new data and the length of the data is returned. If no data is found then\r
+ * uip_buf is not updated and 0 is returned.\r
+ */\r
+unsigned long ulGetEMACRxData( void );\r
+\r
+/*\r
+ * Send usTxDataLen bytes from uip_buf.\r
+ */\r
+void vSendEMACTxData( unsigned short usTxDataLen );\r
+\r
+/*\r
+ * Prepare the Ethernet hardware ready for TCP/IP comms.\r
+ */\r
+long lEMACInit(void);\r
+\r
+#endif\r
--- /dev/null
+/*\r
+ * @file: EthDev_LPC17xx.h\r
+ * @purpose: Ethernet Device Definitions for NXP LPC17xx\r
+ * @version: V0.01\r
+ * @date: 14. May 2009\r
+ *----------------------------------------------------------------------------\r
+ *\r
+ * Copyright (C) 2009 ARM Limited. All rights reserved.\r
+ *\r
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M3\r
+ * processor based microcontrollers. This file can be freely distributed\r
+ * within development tools that are supporting such ARM based processors.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
+ *\r
+ */\r
+\r
+#ifndef __ETHDEV_LPC17XX_H\r
+#define __ETHDEV_LPC17XX_H\r
+\r
+#include <stdint.h>\r
+\r
+/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */\r
+#define NUM_RX_FRAG 3 /* Num.of RX Fragments. */\r
+#define NUM_TX_FRAG 2 /* Num.of TX Fragments. */\r
+#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */\r
+\r
+#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */\r
+\r
+typedef struct { /* RX Descriptor struct */\r
+ uint32_t Packet;\r
+ uint32_t Ctrl;\r
+} RX_DESC_TypeDef;\r
+\r
+typedef struct { /* RX Status struct */\r
+ uint32_t Info;\r
+ uint32_t HashCRC;\r
+} RX_STAT_TypeDef;\r
+\r
+typedef struct { /* TX Descriptor struct */\r
+ uint32_t Packet;\r
+ uint32_t Ctrl;\r
+} TX_DESC_TypeDef;\r
+\r
+typedef struct { /* TX Status struct */\r
+ uint32_t Info;\r
+} TX_STAT_TypeDef;\r
+\r
+\r
+/* EMAC variables located in AHB SRAM bank 1*/\r
+#define AHB_SRAM_BANK1_BASE 0x2007c000UL\r
+#define RX_DESC_BASE (AHB_SRAM_BANK1_BASE )\r
+#define RX_STAT_BASE (RX_DESC_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_DESC_TypeDef */\r
+#define TX_DESC_BASE (RX_STAT_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_STAT_TypeDef */\r
+#define TX_STAT_BASE (TX_DESC_BASE + NUM_TX_FRAG*(2*4)) /* 2 * uint32_t, see TX_DESC_TypeDef */\r
+#define ETH_BUF_BASE (TX_STAT_BASE + NUM_TX_FRAG*(1*4)) /* 1 * uint32_t, see TX_STAT_TypeDef */\r
+\r
+/* RX and TX descriptor and status definitions. */\r
+#define RX_DESC_PACKET(i) (*(unsigned int *)(RX_DESC_BASE + 8*i))\r
+#define RX_DESC_CTRL(i) (*(unsigned int *)(RX_DESC_BASE+4 + 8*i))\r
+#define RX_STAT_INFO(i) (*(unsigned int *)(RX_STAT_BASE + 8*i))\r
+#define RX_STAT_HASHCRC(i) (*(unsigned int *)(RX_STAT_BASE+4 + 8*i))\r
+#define TX_DESC_PACKET(i) (*(unsigned int *)(TX_DESC_BASE + 8*i))\r
+#define TX_DESC_CTRL(i) (*(unsigned int *)(TX_DESC_BASE+4 + 8*i))\r
+#define TX_STAT_INFO(i) (*(unsigned int *)(TX_STAT_BASE + 4*i))\r
+#define ETH_BUF(i) ( ETH_BUF_BASE + ETH_FRAG_SIZE*i )\r
+#define ETH_NUM_BUFFERS ( NUM_TX_FRAG + NUM_RX_FRAG + 1 ) /* There are in fact 2 more buffers than descriptors as the two Tx descriptors use the same buffer to speed up the uip Tx. */\r
+\r
+\r
+/* MAC Configuration Register 1 */\r
+#define MAC1_REC_EN 0x00000001 /* Receive Enable */\r
+#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */\r
+#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */\r
+#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */\r
+#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */\r
+#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */\r
+#define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */\r
+#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */\r
+#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */\r
+#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */\r
+#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */\r
+\r
+/* MAC Configuration Register 2 */\r
+#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */\r
+#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */\r
+#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */\r
+#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */\r
+#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */\r
+#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */\r
+#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */\r
+#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */\r
+#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */\r
+#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */\r
+#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */\r
+#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */\r
+#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */\r
+\r
+/* Back-to-Back Inter-Packet-Gap Register */\r
+#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */\r
+#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */\r
+\r
+/* Non Back-to-Back Inter-Packet-Gap Register */\r
+#define IPGR_DEF 0x00000012 /* Recommended value */\r
+\r
+/* Collision Window/Retry Register */\r
+#define CLRT_DEF 0x0000370F /* Default value */\r
+\r
+/* PHY Support Register */\r
+#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */\r
+#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */\r
+\r
+/* Test Register */\r
+#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */\r
+#define TEST_TST_PAUSE 0x00000002 /* Test Pause */\r
+#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */\r
+\r
+/* MII Management Configuration Register */\r
+#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */\r
+#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */\r
+#define MCFG_CLK_SEL 0x0000003C /* Clock Select Mask */\r
+#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */\r
+\r
+/* MII Management Command Register */\r
+#define MCMD_READ 0x00000001 /* MII Read */\r
+#define MCMD_SCAN 0x00000002 /* MII Scan continuously */\r
+\r
+#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */\r
+#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */\r
+\r
+/* MII Management Address Register */\r
+#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */\r
+#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */\r
+\r
+/* MII Management Indicators Register */\r
+#define MIND_BUSY 0x00000001 /* MII is Busy */\r
+#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */\r
+#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */\r
+#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */\r
+\r
+/* Command Register */\r
+#define CR_RX_EN 0x00000001 /* Enable Receive */\r
+#define CR_TX_EN 0x00000002 /* Enable Transmit */\r
+#define CR_REG_RES 0x00000008 /* Reset Host Registers */\r
+#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */\r
+#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */\r
+#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */\r
+#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */\r
+#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */\r
+#define CR_RMII 0x00000200 /* Reduced MII Interface */\r
+#define CR_FULL_DUP 0x00000400 /* Full Duplex */\r
+\r
+/* Status Register */\r
+#define SR_RX_EN 0x00000001 /* Enable Receive */\r
+#define SR_TX_EN 0x00000002 /* Enable Transmit */\r
+\r
+/* Transmit Status Vector 0 Register */\r
+#define TSV0_CRC_ERR 0x00000001 /* CRC error */\r
+#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */\r
+#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */\r
+#define TSV0_DONE 0x00000008 /* Tramsmission Completed */\r
+#define TSV0_MCAST 0x00000010 /* Multicast Destination */\r
+#define TSV0_BCAST 0x00000020 /* Broadcast Destination */\r
+#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */\r
+#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */\r
+#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */\r
+#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */\r
+#define TSV0_GIANT 0x00000400 /* Giant Frame */\r
+#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */\r
+#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */\r
+#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */\r
+#define TSV0_PAUSE 0x20000000 /* Pause Frame */\r
+#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */\r
+#define TSV0_VLAN 0x80000000 /* VLAN Frame */\r
+\r
+/* Transmit Status Vector 1 Register */\r
+#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */\r
+#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */\r
+\r
+/* Receive Status Vector Register */\r
+#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */\r
+#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */\r
+#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */\r
+#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */\r
+#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */\r
+#define RSV_CRC_ERR 0x00100000 /* CRC Error */\r
+#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */\r
+#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */\r
+#define RSV_REC_OK 0x00800000 /* Frame Received OK */\r
+#define RSV_MCAST 0x01000000 /* Multicast Frame */\r
+#define RSV_BCAST 0x02000000 /* Broadcast Frame */\r
+#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */\r
+#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */\r
+#define RSV_PAUSE 0x10000000 /* Pause Frame */\r
+#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */\r
+#define RSV_VLAN 0x40000000 /* VLAN Frame */\r
+\r
+/* Flow Control Counter Register */\r
+#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */\r
+#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */\r
+\r
+/* Flow Control Status Register */\r
+#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */\r
+\r
+/* Receive Filter Control Register */\r
+#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */\r
+#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */\r
+#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */\r
+#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */\r
+#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/\r
+#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */\r
+#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */\r
+#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */\r
+\r
+/* Receive Filter WoL Status/Clear Registers */\r
+#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */\r
+#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */\r
+#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */\r
+#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */\r
+#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */\r
+#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */\r
+#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */\r
+#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */\r
+\r
+/* Interrupt Status/Enable/Clear/Set Registers */\r
+#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */\r
+#define INT_RX_ERR 0x00000002 /* Receive Error */\r
+#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */\r
+#define INT_RX_DONE 0x00000008 /* Receive Done */\r
+#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */\r
+#define INT_TX_ERR 0x00000020 /* Transmit Error */\r
+#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */\r
+#define INT_TX_DONE 0x00000080 /* Transmit Done */\r
+#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */\r
+#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */\r
+\r
+/* Power Down Register */\r
+#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */\r
+\r
+/* RX Descriptor Control Word */\r
+#define RCTRL_SIZE 0x000007FF /* Buffer size mask */\r
+#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */\r
+\r
+/* RX Status Hash CRC Word */\r
+#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */\r
+#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */\r
+\r
+/* RX Status Information Word */\r
+#define RINFO_SIZE 0x000007FF /* Data size in bytes */\r
+#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */\r
+#define RINFO_VLAN 0x00080000 /* VLAN Frame */\r
+#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */\r
+#define RINFO_MCAST 0x00200000 /* Multicast Frame */\r
+#define RINFO_BCAST 0x00400000 /* Broadcast Frame */\r
+#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */\r
+#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */\r
+#define RINFO_LEN_ERR 0x02000000 /* Length Error */\r
+#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */\r
+#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */\r
+#define RINFO_OVERRUN 0x10000000 /* Receive overrun */\r
+#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */\r
+#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */\r
+#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */\r
+\r
+#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | \\r
+ RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN)\r
+\r
+/* TX Descriptor Control Word */\r
+#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */\r
+#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */\r
+#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */\r
+#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */\r
+#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */\r
+#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */\r
+#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */\r
+\r
+/* TX Status Information Word */\r
+#define TINFO_COL_CNT 0x01E00000 /* Collision Count */\r
+#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */\r
+#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */\r
+#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */\r
+#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */\r
+#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */\r
+#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */\r
+#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */\r
+\r
+/* ENET Device Revision ID */\r
+#define OLD_EMAC_MODULE_ID 0x39022000 /* Rev. ID for first rev '-' */\r
+\r
+/* DP83848C PHY Registers */\r
+#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */\r
+#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */\r
+#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */\r
+#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */\r
+#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */\r
+#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */\r
+#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */\r
+#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */\r
+\r
+/* PHY Extended Registers */\r
+#define PHY_REG_STS 0x10 /* Status Register */\r
+#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */\r
+#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */\r
+#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */\r
+#define PHY_REG_RECR 0x15 /* Receive Error Counter */\r
+#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */\r
+#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */\r
+#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */\r
+#define PHY_REG_PHYCR 0x19 /* PHY Control Register */\r
+#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */\r
+#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */\r
+#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */\r
+\r
+#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */\r
+#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */\r
+#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */\r
+#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */\r
+#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */\r
+#define PHY_AUTO_NEG_COMPLETE 0x0020 /* Auto negotiation have finished. */\r
+\r
+#define DP83848C_DEF_ADR 0x0100 /* Default PHY device address */\r
+#define DP83848C_ID 0x20005C90 /* PHY Identifier */\r
+\r
+#endif\r
+\r
+/*----------------------------------------------------------------------------\r
+ * end of file\r
+ *---------------------------------------------------------------------------*/\r
--- /dev/null
+/*\r
+ FreeRTOS V6.0.2 - Copyright (C) 2010 Real Time Engineers Ltd.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * If you are: *\r
+ * *\r
+ * + New to FreeRTOS, *\r
+ * + Wanting to learn FreeRTOS or multitasking in general quickly *\r
+ * + Looking for basic training, *\r
+ * + Wanting to improve your FreeRTOS skills and productivity *\r
+ * *\r
+ * then take a look at the FreeRTOS eBook *\r
+ * *\r
+ * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ * A pdf reference manual is also available. Both are usually delivered *\r
+ * to your inbox within 20 minutes to two hours when purchased between 8am *\r
+ * and 8pm GMT (although please allow up to 24 hours in case of *\r
+ * exceptional circumstances). Thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ ***NOTE*** The exception to the GPL is included to allow you to distribute\r
+ a combined work that includes FreeRTOS without being obliged to provide the\r
+ source code for proprietary components outside of the FreeRTOS kernel.\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public \r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it \r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained \r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+/* Originally adapted from file written by Andreas Dannenberg. Supplied with permission. */\r
+\r
+/* Kernel includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "semphr.h"\r
+\r
+/* Hardware specific includes. */\r
+#include "EthDev_LPC17xx.h"\r
+\r
+/* Time to wait between each inspection of the link status. */\r
+#define emacWAIT_FOR_LINK_TO_ESTABLISH ( 500 / portTICK_RATE_MS )\r
+\r
+/* Short delay used in several places during the initialisation process. */\r
+#define emacSHORT_DELAY ( 2 )\r
+\r
+/* Hardware specific bit definitions. */\r
+#define emacLINK_ESTABLISHED ( 0x0001 )\r
+#define emacFULL_DUPLEX_ENABLED ( 0x0004 )\r
+#define emac10BASE_T_MODE ( 0x0002 )\r
+#define emacPINSEL2_VALUE ( 0x50150105 )\r
+\r
+/* If no buffers are available, then wait this long before looking again.... */\r
+#define emacBUFFER_WAIT_DELAY ( 3 / portTICK_RATE_MS )\r
+\r
+/* ...and don't look more than this many times. */\r
+#define emacBUFFER_WAIT_ATTEMPTS ( 30 )\r
+\r
+/* Index to the Tx descriptor that is always used first for every Tx. The second\r
+descriptor is then used to re-send in order to speed up the uIP Tx process. */\r
+#define emacTX_DESC_INDEX ( 0 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Configure both the Rx and Tx descriptors during the init process.\r
+ */\r
+static void prvInitDescriptors( void );\r
+\r
+/*\r
+ * Setup the IO and peripherals required for Ethernet communication.\r
+ */\r
+static void prvSetupEMACHardware( void );\r
+\r
+/*\r
+ * Control the auto negotiate process.\r
+ */\r
+static void prvConfigurePHY( void );\r
+\r
+/*\r
+ * Wait for a link to be established, then setup the PHY according to the link\r
+ * parameters.\r
+ */\r
+static long prvSetupLinkStatus( void );\r
+\r
+/*\r
+ * Search the pool of buffers to find one that is free. If a buffer is found\r
+ * mark it as in use before returning its address.\r
+ */\r
+static unsigned char *prvGetNextBuffer( void );\r
+\r
+/*\r
+ * Return an allocated buffer to the pool of free buffers.\r
+ */\r
+static void prvReturnBuffer( unsigned char *pucBuffer );\r
+\r
+/*\r
+ * Send lValue to the lPhyReg within the PHY.\r
+ */\r
+static long prvWritePHY( long lPhyReg, long lValue );\r
+\r
+/*\r
+ * Read a value from ucPhyReg within the PHY. *plStatus will be set to\r
+ * pdFALSE if there is an error.\r
+ */\r
+static unsigned short prvReadPHY( unsigned char ucPhyReg, long *plStatus );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The semaphore used to wake the uIP task when data arrives. */\r
+extern xSemaphoreHandle xEMACSemaphore;\r
+\r
+/* Each ucBufferInUse index corresponds to a position in the pool of buffers.\r
+If the index contains a 1 then the buffer within pool is in use, if it\r
+contains a 0 then the buffer is free. */\r
+static unsigned char ucBufferInUse[ ETH_NUM_BUFFERS ] = { pdFALSE };\r
+\r
+/* The uip_buffer is not a fixed array, but instead gets pointed to the buffers\r
+allocated within this file. */\r
+unsigned char * uip_buf;\r
+\r
+/* Store the length of the data being sent so the data can be sent twice. The\r
+value will be set back to 0 once the data has been sent twice. */\r
+static unsigned short usSendLen = 0;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+long lEMACInit( void )\r
+{\r
+long lReturn = pdPASS;\r
+unsigned long ulID1, ulID2;\r
+\r
+ /* Reset peripherals, configure port pins and registers. */\r
+ prvSetupEMACHardware();\r
+\r
+ /* Check the PHY part number is as expected. */\r
+ ulID1 = prvReadPHY( PHY_REG_IDR1, &lReturn );\r
+ ulID2 = prvReadPHY( PHY_REG_IDR2, &lReturn );\r
+ if( ( (ulID1 << 16UL ) | ( ulID2 & 0xFFF0UL ) ) == DP83848C_ID )\r
+ {\r
+ /* Set the Ethernet MAC Address registers */\r
+ EMAC->SA0 = ( configMAC_ADDR0 << 8 ) | configMAC_ADDR1;\r
+ EMAC->SA1 = ( configMAC_ADDR2 << 8 ) | configMAC_ADDR3;\r
+ EMAC->SA2 = ( configMAC_ADDR4 << 8 ) | configMAC_ADDR5;\r
+\r
+ /* Initialize Tx and Rx DMA Descriptors */\r
+ prvInitDescriptors();\r
+\r
+ /* Receive broadcast and perfect match packets */\r
+ EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;\r
+\r
+ /* Setup the PHY. */\r
+ prvConfigurePHY();\r
+ }\r
+ else\r
+ {\r
+ lReturn = pdFAIL;\r
+ }\r
+\r
+ /* Check the link status. */\r
+ if( lReturn == pdPASS )\r
+ {\r
+ lReturn = prvSetupLinkStatus();\r
+ }\r
+\r
+ if( lReturn == pdPASS )\r
+ {\r
+ /* Initialise uip_buf to ensure it points somewhere valid. */\r
+ uip_buf = prvGetNextBuffer();\r
+\r
+ /* Reset all interrupts */\r
+ EMAC->IntClear = ( INT_RX_OVERRUN | INT_RX_ERR | INT_RX_FIN | INT_RX_DONE | INT_TX_UNDERRUN | INT_TX_ERR | INT_TX_FIN | INT_TX_DONE | INT_SOFT_INT | INT_WAKEUP );\r
+\r
+ /* Enable receive and transmit mode of MAC Ethernet core */\r
+ EMAC->Command |= ( CR_RX_EN | CR_TX_EN );\r
+ EMAC->MAC1 |= MAC1_REC_EN;\r
+ }\r
+\r
+ return lReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static unsigned char *prvGetNextBuffer( void )\r
+{\r
+long x;\r
+unsigned char *pucReturn = NULL;\r
+unsigned long ulAttempts = 0;\r
+\r
+ while( pucReturn == NULL )\r
+ {\r
+ /* Look through the buffers to find one that is not in use by\r
+ anything else. */\r
+ for( x = 0; x < ETH_NUM_BUFFERS; x++ )\r
+ {\r
+ if( ucBufferInUse[ x ] == pdFALSE )\r
+ {\r
+ ucBufferInUse[ x ] = pdTRUE;\r
+ pucReturn = ( unsigned char * ) ETH_BUF( x );\r
+ break;\r
+ }\r
+ }\r
+\r
+ /* Was a buffer found? */\r
+ if( pucReturn == NULL )\r
+ {\r
+ ulAttempts++;\r
+\r
+ if( ulAttempts >= emacBUFFER_WAIT_ATTEMPTS )\r
+ {\r
+ break;\r
+ }\r
+\r
+ /* Wait then look again. */\r
+ vTaskDelay( emacBUFFER_WAIT_DELAY );\r
+ }\r
+ }\r
+\r
+ return pucReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvInitDescriptors( void )\r
+{\r
+long x, lNextBuffer = 0;\r
+\r
+ for( x = 0; x < NUM_RX_FRAG; x++ )\r
+ {\r
+ /* Allocate the next Ethernet buffer to this descriptor. */\r
+ RX_DESC_PACKET( x ) = ETH_BUF( lNextBuffer );\r
+ RX_DESC_CTRL( x ) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 );\r
+ RX_STAT_INFO( x ) = 0;\r
+ RX_STAT_HASHCRC( x ) = 0;\r
+\r
+ /* The Ethernet buffer is now in use. */\r
+ ucBufferInUse[ lNextBuffer ] = pdTRUE;\r
+ lNextBuffer++;\r
+ }\r
+\r
+ /* Set EMAC Receive Descriptor Registers. */\r
+ EMAC->RxDescriptor = RX_DESC_BASE;\r
+ EMAC->RxStatus = RX_STAT_BASE;\r
+ EMAC->RxDescriptorNumber = NUM_RX_FRAG - 1;\r
+\r
+ /* Rx Descriptors Point to 0 */\r
+ EMAC->RxConsumeIndex = 0;\r
+\r
+ /* A buffer is not allocated to the Tx descriptors until they are actually\r
+ used. */\r
+ for( x = 0; x < NUM_TX_FRAG; x++ )\r
+ {\r
+ TX_DESC_PACKET( x ) = ( unsigned long ) NULL;\r
+ TX_DESC_CTRL( x ) = 0;\r
+ TX_STAT_INFO( x ) = 0;\r
+ }\r
+\r
+ /* Set EMAC Transmit Descriptor Registers. */\r
+ EMAC->TxDescriptor = TX_DESC_BASE;\r
+ EMAC->TxStatus = TX_STAT_BASE;\r
+ EMAC->TxDescriptorNumber = NUM_TX_FRAG - 1;\r
+\r
+ /* Tx Descriptors Point to 0 */\r
+ EMAC->TxProduceIndex = 0;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSetupEMACHardware( void )\r
+{\r
+unsigned short us;\r
+long x, lDummy;\r
+\r
+ /* Enable P1 Ethernet Pins. */\r
+ PINCON->PINSEL2 = emacPINSEL2_VALUE;\r
+ PINCON->PINSEL3 = ( PINCON->PINSEL3 & ~0x0000000F ) | 0x00000005;\r
+\r
+ /* Power Up the EMAC controller. */\r
+ SC->PCONP |= PCONP_PCENET;\r
+ vTaskDelay( emacSHORT_DELAY );\r
+\r
+ /* Reset all EMAC internal modules. */\r
+ EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES;\r
+ EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM;\r
+\r
+ /* A short delay after reset. */\r
+ vTaskDelay( emacSHORT_DELAY );\r
+\r
+ /* Initialize MAC control registers. */\r
+ EMAC->MAC1 = MAC1_PASS_ALL;\r
+ EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;\r
+ EMAC->MAXF = ETH_MAX_FLEN;\r
+ EMAC->CLRT = CLRT_DEF;\r
+ EMAC->IPGR = IPGR_DEF;\r
+\r
+ /* Enable Reduced MII interface. */\r
+ EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM;\r
+\r
+ /* Reset Reduced MII Logic. */\r
+ EMAC->SUPP = SUPP_RES_RMII;\r
+ vTaskDelay( emacSHORT_DELAY );\r
+ EMAC->SUPP = 0;\r
+\r
+ /* Put the PHY in reset mode */\r
+ prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII );\r
+ prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII );\r
+\r
+ /* Wait for hardware reset to end. */\r
+ for( x = 0; x < 100; x++ )\r
+ {\r
+ vTaskDelay( emacSHORT_DELAY * 5 );\r
+ us = prvReadPHY( PHY_REG_BMCR, &lDummy );\r
+ if( !( us & MCFG_RES_MII ) )\r
+ {\r
+ /* Reset complete */\r
+ break;\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvConfigurePHY( void )\r
+{\r
+unsigned short us;\r
+long x, lDummy;\r
+\r
+ /* Auto negotiate the configuration. */\r
+ if( prvWritePHY( PHY_REG_BMCR, PHY_AUTO_NEG ) )\r
+ {\r
+ vTaskDelay( emacSHORT_DELAY * 5 );\r
+\r
+ for( x = 0; x < 10; x++ )\r
+ {\r
+ us = prvReadPHY( PHY_REG_BMSR, &lDummy );\r
+\r
+ if( us & PHY_AUTO_NEG_COMPLETE )\r
+ {\r
+ break;\r
+ }\r
+\r
+ vTaskDelay( emacWAIT_FOR_LINK_TO_ESTABLISH );\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static long prvSetupLinkStatus( void )\r
+{\r
+long lReturn = pdFAIL, x;\r
+unsigned short usLinkStatus;\r
+\r
+ /* Wait with timeout for the link to be established. */\r
+ for( x = 0; x < 10; x++ )\r
+ {\r
+ usLinkStatus = prvReadPHY( PHY_REG_STS, &lReturn );\r
+ if( usLinkStatus & emacLINK_ESTABLISHED )\r
+ {\r
+ /* Link is established. */\r
+ lReturn = pdPASS;\r
+ break;\r
+ }\r
+\r
+ vTaskDelay( emacWAIT_FOR_LINK_TO_ESTABLISH );\r
+ }\r
+\r
+ if( lReturn == pdPASS )\r
+ {\r
+ /* Configure Full/Half Duplex mode. */\r
+ if( usLinkStatus & emacFULL_DUPLEX_ENABLED )\r
+ {\r
+ /* Full duplex is enabled. */\r
+ EMAC->MAC2 |= MAC2_FULL_DUP;\r
+ EMAC->Command |= CR_FULL_DUP;\r
+ EMAC->IPGT = IPGT_FULL_DUP;\r
+ }\r
+ else\r
+ {\r
+ /* Half duplex mode. */\r
+ EMAC->IPGT = IPGT_HALF_DUP;\r
+ }\r
+\r
+ /* Configure 100MBit/10MBit mode. */\r
+ if( usLinkStatus & emac10BASE_T_MODE )\r
+ {\r
+ /* 10MBit mode. */\r
+ EMAC->SUPP = 0;\r
+ }\r
+ else\r
+ {\r
+ /* 100MBit mode. */\r
+ EMAC->SUPP = SUPP_SPEED;\r
+ }\r
+ }\r
+\r
+ return lReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvReturnBuffer( unsigned char *pucBuffer )\r
+{\r
+unsigned long ul;\r
+\r
+ /* Return a buffer to the pool of free buffers. */\r
+ for( ul = 0; ul < ETH_NUM_BUFFERS; ul++ )\r
+ {\r
+ if( ETH_BUF( ul ) == ( unsigned long ) pucBuffer )\r
+ {\r
+ ucBufferInUse[ ul ] = pdFALSE;\r
+ break;\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+unsigned long ulGetEMACRxData( void )\r
+{\r
+unsigned long ulLen = 0;\r
+long lIndex;\r
+\r
+ if( EMAC->RxProduceIndex != EMAC->RxConsumeIndex )\r
+ {\r
+ /* Mark the current buffer as free as uip_buf is going to be set to\r
+ the buffer that contains the received data. */\r
+ prvReturnBuffer( uip_buf );\r
+\r
+ ulLen = ( RX_STAT_INFO( EMAC->RxConsumeIndex ) & RINFO_SIZE ) - 3;\r
+ uip_buf = ( unsigned char * ) RX_DESC_PACKET( EMAC->RxConsumeIndex );\r
+\r
+ /* Allocate a new buffer to the descriptor. */\r
+ RX_DESC_PACKET( EMAC->RxConsumeIndex ) = ( unsigned long ) prvGetNextBuffer();\r
+\r
+ /* Move the consume index onto the next position, ensuring it wraps to\r
+ the beginning at the appropriate place. */\r
+ lIndex = EMAC->RxConsumeIndex;\r
+\r
+ lIndex++;\r
+ if( lIndex >= NUM_RX_FRAG )\r
+ {\r
+ lIndex = 0;\r
+ }\r
+\r
+ EMAC->RxConsumeIndex = lIndex;\r
+ }\r
+\r
+ return ulLen;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vSendEMACTxData( unsigned short usTxDataLen )\r
+{\r
+unsigned long ulAttempts = 0UL;\r
+\r
+ /* Check to see if the Tx descriptor is free, indicated by its buffer being\r
+ NULL. */\r
+ while( TX_DESC_PACKET( emacTX_DESC_INDEX ) != ( unsigned long ) NULL )\r
+ {\r
+ /* Wait for the Tx descriptor to become available. */\r
+ vTaskDelay( emacBUFFER_WAIT_DELAY );\r
+\r
+ ulAttempts++;\r
+ if( ulAttempts > emacBUFFER_WAIT_ATTEMPTS )\r
+ {\r
+ /* Something has gone wrong as the Tx descriptor is still in use.\r
+ Clear it down manually, the data it was sending will probably be\r
+ lost. */\r
+ prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );\r
+ break;\r
+ }\r
+ }\r
+\r
+ /* Setup the Tx descriptor for transmission. Remember the length of the\r
+ data being sent so the second descriptor can be used to send it again from\r
+ within the ISR. */\r
+ usSendLen = usTxDataLen;\r
+ TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) uip_buf;\r
+ TX_DESC_CTRL( emacTX_DESC_INDEX ) = ( usTxDataLen | TCTRL_LAST | TCTRL_INT );\r
+ EMAC->TxProduceIndex = ( emacTX_DESC_INDEX + 1 );\r
+\r
+ /* uip_buf is being sent by the Tx descriptor. Allocate a new buffer. */\r
+ uip_buf = prvGetNextBuffer();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static long prvWritePHY( long lPhyReg, long lValue )\r
+{\r
+const long lMaxTime = 10;\r
+long x;\r
+\r
+ EMAC->MADR = DP83848C_DEF_ADR | lPhyReg;\r
+ EMAC->MWTD = lValue;\r
+\r
+ x = 0;\r
+ for( x = 0; x < lMaxTime; x++ )\r
+ {\r
+ if( ( EMAC->MIND & MIND_BUSY ) == 0 )\r
+ {\r
+ /* Operation has finished. */\r
+ break;\r
+ }\r
+\r
+ vTaskDelay( emacSHORT_DELAY );\r
+ }\r
+\r
+ if( x < lMaxTime )\r
+ {\r
+ return pdPASS;\r
+ }\r
+ else\r
+ {\r
+ return pdFAIL;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static unsigned short prvReadPHY( unsigned char ucPhyReg, long *plStatus )\r
+{\r
+long x;\r
+const long lMaxTime = 10;\r
+\r
+ EMAC->MADR = DP83848C_DEF_ADR | ucPhyReg;\r
+ EMAC->MCMD = MCMD_READ;\r
+\r
+ for( x = 0; x < lMaxTime; x++ )\r
+ {\r
+ /* Operation has finished. */\r
+ if( ( EMAC->MIND & MIND_BUSY ) == 0 )\r
+ {\r
+ break;\r
+ }\r
+\r
+ vTaskDelay( emacSHORT_DELAY );\r
+ }\r
+\r
+ EMAC->MCMD = 0;\r
+\r
+ if( x >= lMaxTime )\r
+ {\r
+ *plStatus = pdFAIL;\r
+ }\r
+\r
+ return( EMAC->MRDD );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vEMAC_ISR( void )\r
+{\r
+unsigned long ulStatus;\r
+long lHigherPriorityTaskWoken = pdFALSE;\r
+\r
+ ulStatus = EMAC->IntStatus;\r
+\r
+ /* Clear the interrupt. */\r
+ EMAC->IntClear = ulStatus;\r
+\r
+ if( ulStatus & INT_RX_DONE )\r
+ {\r
+ /* Ensure the uIP task is not blocked as data has arrived. */\r
+ xSemaphoreGiveFromISR( xEMACSemaphore, &lHigherPriorityTaskWoken );\r
+ }\r
+\r
+ if( ulStatus & INT_TX_DONE )\r
+ {\r
+ if( usSendLen > 0 )\r
+ {\r
+ /* Send the data again, using the second descriptor. As there are\r
+ only two descriptors the index is set back to 0. */\r
+ TX_DESC_PACKET( ( emacTX_DESC_INDEX + 1 ) ) = TX_DESC_PACKET( emacTX_DESC_INDEX );\r
+ TX_DESC_CTRL( ( emacTX_DESC_INDEX + 1 ) ) = ( usSendLen | TCTRL_LAST | TCTRL_INT );\r
+ EMAC->TxProduceIndex = ( emacTX_DESC_INDEX );\r
+\r
+ /* This is the second Tx so set usSendLen to 0 to indicate that the\r
+ Tx descriptors will be free again. */\r
+ usSendLen = 0UL;\r
+ }\r
+ else\r
+ {\r
+ /* The Tx buffer is no longer required. */\r
+ prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );\r
+ TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) NULL;\r
+ }\r
+ }\r
+\r
+ portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );\r
+}\r