These are the examples provided for [[/users/frank26080115/libraries/LPC1700CMSIS_Lib/]] Note, the entire "program" is not compilable!
SPI/SDCard/spi_sdcard.c@0:bf7b9fba3924, 2011-03-20 (annotated)
- Committer:
- frank26080115
- Date:
- Sun Mar 20 05:38:56 2011 +0000
- Revision:
- 0:bf7b9fba3924
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
frank26080115 | 0:bf7b9fba3924 | 1 | /******************** (C) COPYRIGHT 2010 NXPSemiconductors ************ |
frank26080115 | 0:bf7b9fba3924 | 2 | * @file spi_sdcard.c |
frank26080115 | 0:bf7b9fba3924 | 3 | * @purpose This example describes how to use SPI at mode SPI master/8bit |
frank26080115 | 0:bf7b9fba3924 | 4 | * on LPC1768 to communicate with SC16IS750/760 Demo board |
frank26080115 | 0:bf7b9fba3924 | 5 | * in interrupt mode |
frank26080115 | 0:bf7b9fba3924 | 6 | * @version 1.0 |
frank26080115 | 0:bf7b9fba3924 | 7 | * @date 16. July. 2010 |
frank26080115 | 0:bf7b9fba3924 | 8 | * @author NXP MCU SW Application Team |
frank26080115 | 0:bf7b9fba3924 | 9 | *--------------------------------------------------------------------- |
frank26080115 | 0:bf7b9fba3924 | 10 | * Software that is described herein is for illustrative purposes only |
frank26080115 | 0:bf7b9fba3924 | 11 | * which provides customers with programming information regarding the |
frank26080115 | 0:bf7b9fba3924 | 12 | * products. This software is supplied "AS IS" without any warranties. |
frank26080115 | 0:bf7b9fba3924 | 13 | * NXP Semiconductors assumes no responsibility or liability for the |
frank26080115 | 0:bf7b9fba3924 | 14 | * use of the software, conveys no license or title under any patent, |
frank26080115 | 0:bf7b9fba3924 | 15 | * copyright, or mask work right to the product. NXP Semiconductors |
frank26080115 | 0:bf7b9fba3924 | 16 | * reserves the right to make changes in the software without |
frank26080115 | 0:bf7b9fba3924 | 17 | * notification. NXP Semiconductors also make no representation or |
frank26080115 | 0:bf7b9fba3924 | 18 | * warranty that such application will be suitable for the specified |
frank26080115 | 0:bf7b9fba3924 | 19 | * use without further testing or modification. |
frank26080115 | 0:bf7b9fba3924 | 20 | **********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 21 | #include "lpc17xx_spi.h" |
frank26080115 | 0:bf7b9fba3924 | 22 | #include "lpc17xx_libcfg.h" |
frank26080115 | 0:bf7b9fba3924 | 23 | #include "lpc17xx_pinsel.h" |
frank26080115 | 0:bf7b9fba3924 | 24 | #include "debug_frmwrk.h" |
frank26080115 | 0:bf7b9fba3924 | 25 | #include "lpc17xx_gpio.h" |
frank26080115 | 0:bf7b9fba3924 | 26 | |
frank26080115 | 0:bf7b9fba3924 | 27 | /* Example group ----------------------------------------------------------- */ |
frank26080115 | 0:bf7b9fba3924 | 28 | /** @defgroup SPI_SDCard SDCard |
frank26080115 | 0:bf7b9fba3924 | 29 | * @ingroup SPI_Examples |
frank26080115 | 0:bf7b9fba3924 | 30 | * @{ |
frank26080115 | 0:bf7b9fba3924 | 31 | */ |
frank26080115 | 0:bf7b9fba3924 | 32 | |
frank26080115 | 0:bf7b9fba3924 | 33 | /************************** PRIVATE DEFINTIONS *********************/ |
frank26080115 | 0:bf7b9fba3924 | 34 | // PORT number that /CS pin assigned on |
frank26080115 | 0:bf7b9fba3924 | 35 | #define CS_PORT_NUM 0 |
frank26080115 | 0:bf7b9fba3924 | 36 | // PIN number that /CS pin assigned on |
frank26080115 | 0:bf7b9fba3924 | 37 | #define CS_PIN_NUM 16 |
frank26080115 | 0:bf7b9fba3924 | 38 | |
frank26080115 | 0:bf7b9fba3924 | 39 | #define SD_DETECT_PORTNUM 4 |
frank26080115 | 0:bf7b9fba3924 | 40 | #define SD_DETECT_PINNUM 29 |
frank26080115 | 0:bf7b9fba3924 | 41 | typedef enum _sd_connect_status |
frank26080115 | 0:bf7b9fba3924 | 42 | { |
frank26080115 | 0:bf7b9fba3924 | 43 | SD_CONNECTED, |
frank26080115 | 0:bf7b9fba3924 | 44 | SD_DISCONNECTED |
frank26080115 | 0:bf7b9fba3924 | 45 | }sd_connect_status; |
frank26080115 | 0:bf7b9fba3924 | 46 | typedef enum _sd_error |
frank26080115 | 0:bf7b9fba3924 | 47 | { |
frank26080115 | 0:bf7b9fba3924 | 48 | SD_OK, |
frank26080115 | 0:bf7b9fba3924 | 49 | SD_NG, |
frank26080115 | 0:bf7b9fba3924 | 50 | SD_CMD_BAD_PARAMETER, |
frank26080115 | 0:bf7b9fba3924 | 51 | SD_ERROR_TOKEN, |
frank26080115 | 0:bf7b9fba3924 | 52 | SD_ERROR_TIMEOUT, |
frank26080115 | 0:bf7b9fba3924 | 53 | SD_ERROR_BUS_NOT_IDLE, |
frank26080115 | 0:bf7b9fba3924 | 54 | SD_ERROR_CMD0, |
frank26080115 | 0:bf7b9fba3924 | 55 | SD_ERROR_CMD55, |
frank26080115 | 0:bf7b9fba3924 | 56 | SD_ERROR_ACMD41, |
frank26080115 | 0:bf7b9fba3924 | 57 | SD_ERROR_CMD59, |
frank26080115 | 0:bf7b9fba3924 | 58 | }sd_error; |
frank26080115 | 0:bf7b9fba3924 | 59 | |
frank26080115 | 0:bf7b9fba3924 | 60 | //SD command code |
frank26080115 | 0:bf7b9fba3924 | 61 | #define CMD0_GO_IDLE_STATE 0x00 |
frank26080115 | 0:bf7b9fba3924 | 62 | #define CMD1_SEND_OPCOND 0x01 |
frank26080115 | 0:bf7b9fba3924 | 63 | #define CMD9_SEND_CSD 0x09 |
frank26080115 | 0:bf7b9fba3924 | 64 | #define CMD10_SEND_CID 0x0a |
frank26080115 | 0:bf7b9fba3924 | 65 | #define CMD12_STOP_TRANSMISSION 0x0b |
frank26080115 | 0:bf7b9fba3924 | 66 | #define CMD13_SEND_STATUS 0x0c |
frank26080115 | 0:bf7b9fba3924 | 67 | #define CMD16_SET_BLOCKLEN 0x10 |
frank26080115 | 0:bf7b9fba3924 | 68 | #define CMD17_READ_SINGLE_BLOCK 0x11 |
frank26080115 | 0:bf7b9fba3924 | 69 | #define CMD18_READ_MULTIPLE_BLOCK 0x12 |
frank26080115 | 0:bf7b9fba3924 | 70 | #define CMD24_WRITE_BLOCK 0x18 |
frank26080115 | 0:bf7b9fba3924 | 71 | #define CMD25_WRITE_MULTIPLE_BLOCK 0x19 |
frank26080115 | 0:bf7b9fba3924 | 72 | #define CMD27_PROGRAM_CSD 0x1b |
frank26080115 | 0:bf7b9fba3924 | 73 | #define CMD28_SET_WRITE_PROT 0x1c |
frank26080115 | 0:bf7b9fba3924 | 74 | #define CMD29_CLR_WRITE_PROT 0x1d |
frank26080115 | 0:bf7b9fba3924 | 75 | #define CMD30_SEND_WRITE_PROT 0x1e |
frank26080115 | 0:bf7b9fba3924 | 76 | #define CMD32_ERASE_WR_BLK_START_ADDR 0x20 |
frank26080115 | 0:bf7b9fba3924 | 77 | #define CMD33_ERASE_WR_BLK_END_ADDR 0x21 |
frank26080115 | 0:bf7b9fba3924 | 78 | #define CMD38_ERASE 0x26 |
frank26080115 | 0:bf7b9fba3924 | 79 | #define CMD55_APP_CMD 0x37 |
frank26080115 | 0:bf7b9fba3924 | 80 | #define CMD56_GEN_CMD 0x38 |
frank26080115 | 0:bf7b9fba3924 | 81 | #define CMD58_READ_OCR 0x3a |
frank26080115 | 0:bf7b9fba3924 | 82 | #define CMD59_CRC_ON_OFF 0x3b |
frank26080115 | 0:bf7b9fba3924 | 83 | /* Application-specific commands (always prefixed with CMD55_APP_CMD) */ |
frank26080115 | 0:bf7b9fba3924 | 84 | #define ACMD13_SD_STATUS 0x0d |
frank26080115 | 0:bf7b9fba3924 | 85 | #define ACMD22_SEND_NUM_WR_BLOCKS 0x16 |
frank26080115 | 0:bf7b9fba3924 | 86 | #define ACMD23_SET_WR_BLK_ERASE_COUNT 0x17 |
frank26080115 | 0:bf7b9fba3924 | 87 | #define ACMD41_SEND_OP_COND 0x29 |
frank26080115 | 0:bf7b9fba3924 | 88 | #define ACMD42_SET_CLR_CARD_DETECT 0x2a |
frank26080115 | 0:bf7b9fba3924 | 89 | #define ACMD51_SEND_SCR 0x33 |
frank26080115 | 0:bf7b9fba3924 | 90 | /* R1 format responses (ORed together as a bit-field) */ |
frank26080115 | 0:bf7b9fba3924 | 91 | #define R1_NOERROR 0x00 |
frank26080115 | 0:bf7b9fba3924 | 92 | #define R1_IDLE 0x01 |
frank26080115 | 0:bf7b9fba3924 | 93 | #define R1_ERASE 0x02 |
frank26080115 | 0:bf7b9fba3924 | 94 | #define R1_ILLEGAL 0x04 |
frank26080115 | 0:bf7b9fba3924 | 95 | #define R1_CRC_ERR 0x08 |
frank26080115 | 0:bf7b9fba3924 | 96 | #define R1_ERASE_SEQ 0x10 |
frank26080115 | 0:bf7b9fba3924 | 97 | #define R1_ADDR_ERR 0x20 |
frank26080115 | 0:bf7b9fba3924 | 98 | #define R1_PARAM_ERR 0x40 |
frank26080115 | 0:bf7b9fba3924 | 99 | /* R2 format responses - second byte only, first is identical to R1 */ |
frank26080115 | 0:bf7b9fba3924 | 100 | #define R2_LOCKED 0x01 |
frank26080115 | 0:bf7b9fba3924 | 101 | #define R2_WP_FAILED 0x02 |
frank26080115 | 0:bf7b9fba3924 | 102 | #define R2_ERROR 0x04 |
frank26080115 | 0:bf7b9fba3924 | 103 | #define R2_CTRL_ERR 0x08 |
frank26080115 | 0:bf7b9fba3924 | 104 | #define R2_ECC_FAIL 0x10 |
frank26080115 | 0:bf7b9fba3924 | 105 | #define R2_WP_VIOL 0x20 |
frank26080115 | 0:bf7b9fba3924 | 106 | #define R2_ERASE_PARAM 0x40 |
frank26080115 | 0:bf7b9fba3924 | 107 | #define R2_RANGE_ERR 0x80 |
frank26080115 | 0:bf7b9fba3924 | 108 | |
frank26080115 | 0:bf7b9fba3924 | 109 | #define GETBIT(in, bit) ((in & (1<<bit)) >> bit) |
frank26080115 | 0:bf7b9fba3924 | 110 | #define SD_CMD_BLOCK_LENGTH 6 |
frank26080115 | 0:bf7b9fba3924 | 111 | #define SD_DATA_BLOCK_LENGTH 515 |
frank26080115 | 0:bf7b9fba3924 | 112 | #define SD_WAIT_R1_TIMEOUT 100000 |
frank26080115 | 0:bf7b9fba3924 | 113 | /************************** PRIVATE VARIABLES *************************/ |
frank26080115 | 0:bf7b9fba3924 | 114 | uint8_t menu1[] = |
frank26080115 | 0:bf7b9fba3924 | 115 | "********************************************************************************\n\r" |
frank26080115 | 0:bf7b9fba3924 | 116 | "Hello NXP Semiconductors \n\r" |
frank26080115 | 0:bf7b9fba3924 | 117 | "SPI communicate with SD card demo \n\r" |
frank26080115 | 0:bf7b9fba3924 | 118 | "\t - MCU: LPC17xx \n\r" |
frank26080115 | 0:bf7b9fba3924 | 119 | "\t - Core: ARM Cortex-M3 \n\r" |
frank26080115 | 0:bf7b9fba3924 | 120 | "\t - Communicate via: UART0 - 115200bps \n\r" |
frank26080115 | 0:bf7b9fba3924 | 121 | " Demo SPI module, read SD card's CID register and display via UART0\n\r" |
frank26080115 | 0:bf7b9fba3924 | 122 | "********************************************************************************\n\r"; |
frank26080115 | 0:bf7b9fba3924 | 123 | // SPI Configuration structure variable |
frank26080115 | 0:bf7b9fba3924 | 124 | SPI_CFG_Type SPI_ConfigStruct; |
frank26080115 | 0:bf7b9fba3924 | 125 | // SPI Data Setup structure variable |
frank26080115 | 0:bf7b9fba3924 | 126 | SPI_DATA_SETUP_Type xferConfig; |
frank26080115 | 0:bf7b9fba3924 | 127 | |
frank26080115 | 0:bf7b9fba3924 | 128 | uint8_t sd_cmd_buf[SD_CMD_BLOCK_LENGTH]; |
frank26080115 | 0:bf7b9fba3924 | 129 | uint8_t sd_data_buf[SD_DATA_BLOCK_LENGTH]; |
frank26080115 | 0:bf7b9fba3924 | 130 | /************************** PRIVATE FUNCTIONS *************************/ |
frank26080115 | 0:bf7b9fba3924 | 131 | void CS_Init(void); |
frank26080115 | 0:bf7b9fba3924 | 132 | void CS_Force(int32_t state); |
frank26080115 | 0:bf7b9fba3924 | 133 | void print_menu(void); |
frank26080115 | 0:bf7b9fba3924 | 134 | sd_connect_status SD_GetCardConnectStatus(void); |
frank26080115 | 0:bf7b9fba3924 | 135 | uint8_t crc_7(uint8_t old_crc, uint8_t data); |
frank26080115 | 0:bf7b9fba3924 | 136 | uint8_t crc_7final(uint8_t old_crc); |
frank26080115 | 0:bf7b9fba3924 | 137 | uint32_t SD_SendReceiveData_Polling(void* tx_buf, void* rx_buf, uint32_t length); |
frank26080115 | 0:bf7b9fba3924 | 138 | void SD_SendCommand(uint8_t cmd, uint8_t *arg); |
frank26080115 | 0:bf7b9fba3924 | 139 | sd_error SD_WaitR1(uint8_t *buffer, uint32_t length, uint32_t timeout); |
frank26080115 | 0:bf7b9fba3924 | 140 | sd_error SD_WaitDeviceIdle(uint32_t num_char); |
frank26080115 | 0:bf7b9fba3924 | 141 | sd_error SD_Init(uint8_t retries); |
frank26080115 | 0:bf7b9fba3924 | 142 | sd_error SD_GetCID(void); |
frank26080115 | 0:bf7b9fba3924 | 143 | /*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 144 | |
frank26080115 | 0:bf7b9fba3924 | 145 | /*-------------------------PRIVATE FUNCTIONS------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 146 | |
frank26080115 | 0:bf7b9fba3924 | 147 | /*********************************************************************//** |
frank26080115 | 0:bf7b9fba3924 | 148 | * @brief Initialize CS pin as GPIO function to drive /CS pin |
frank26080115 | 0:bf7b9fba3924 | 149 | * due to definition of CS_PORT_NUM and CS_PORT_NUM |
frank26080115 | 0:bf7b9fba3924 | 150 | * @param None |
frank26080115 | 0:bf7b9fba3924 | 151 | * @return None |
frank26080115 | 0:bf7b9fba3924 | 152 | ***********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 153 | void CS_Init(void) |
frank26080115 | 0:bf7b9fba3924 | 154 | { |
frank26080115 | 0:bf7b9fba3924 | 155 | GPIO_SetDir(CS_PORT_NUM, (1<<CS_PIN_NUM), 1); |
frank26080115 | 0:bf7b9fba3924 | 156 | GPIO_SetValue(CS_PORT_NUM, (1<<CS_PIN_NUM)); |
frank26080115 | 0:bf7b9fba3924 | 157 | } |
frank26080115 | 0:bf7b9fba3924 | 158 | /*********************************************************************//** |
frank26080115 | 0:bf7b9fba3924 | 159 | * @brief Drive CS output pin to low/high level to select slave device |
frank26080115 | 0:bf7b9fba3924 | 160 | * via /CS pin state |
frank26080115 | 0:bf7b9fba3924 | 161 | * @param[in] state State of CS output pin that will be driven: |
frank26080115 | 0:bf7b9fba3924 | 162 | * - 0: Drive CS pin to low level |
frank26080115 | 0:bf7b9fba3924 | 163 | * - 1: Drive CS pin to high level |
frank26080115 | 0:bf7b9fba3924 | 164 | * @return None |
frank26080115 | 0:bf7b9fba3924 | 165 | ***********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 166 | void CS_Force(int32_t state) |
frank26080115 | 0:bf7b9fba3924 | 167 | { |
frank26080115 | 0:bf7b9fba3924 | 168 | if (state){ |
frank26080115 | 0:bf7b9fba3924 | 169 | GPIO_SetValue(CS_PORT_NUM, (1<<CS_PIN_NUM)); |
frank26080115 | 0:bf7b9fba3924 | 170 | }else{ |
frank26080115 | 0:bf7b9fba3924 | 171 | GPIO_ClearValue(CS_PORT_NUM, (1<<CS_PIN_NUM)); |
frank26080115 | 0:bf7b9fba3924 | 172 | } |
frank26080115 | 0:bf7b9fba3924 | 173 | } |
frank26080115 | 0:bf7b9fba3924 | 174 | /*********************************************************************//** |
frank26080115 | 0:bf7b9fba3924 | 175 | * @brief Print Welcome menu |
frank26080115 | 0:bf7b9fba3924 | 176 | * @param[in] none |
frank26080115 | 0:bf7b9fba3924 | 177 | * @return None |
frank26080115 | 0:bf7b9fba3924 | 178 | **********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 179 | void print_menu(void) |
frank26080115 | 0:bf7b9fba3924 | 180 | { |
frank26080115 | 0:bf7b9fba3924 | 181 | _DBG(menu1); |
frank26080115 | 0:bf7b9fba3924 | 182 | } |
frank26080115 | 0:bf7b9fba3924 | 183 | /*********************************************************************//** |
frank26080115 | 0:bf7b9fba3924 | 184 | * @brief check if SD card is inserted or not |
frank26080115 | 0:bf7b9fba3924 | 185 | * @param[in] none |
frank26080115 | 0:bf7b9fba3924 | 186 | * @return SD_CONNECTED or SD_DISCONNECTED |
frank26080115 | 0:bf7b9fba3924 | 187 | **********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 188 | sd_connect_status SD_GetCardConnectStatus(void) |
frank26080115 | 0:bf7b9fba3924 | 189 | { |
frank26080115 | 0:bf7b9fba3924 | 190 | sd_connect_status ret=SD_DISCONNECTED; |
frank26080115 | 0:bf7b9fba3924 | 191 | |
frank26080115 | 0:bf7b9fba3924 | 192 | if((GPIO_ReadValue(SD_DETECT_PORTNUM)&(1<<SD_DETECT_PINNUM))== 0) |
frank26080115 | 0:bf7b9fba3924 | 193 | ret = SD_CONNECTED; |
frank26080115 | 0:bf7b9fba3924 | 194 | |
frank26080115 | 0:bf7b9fba3924 | 195 | return ret; |
frank26080115 | 0:bf7b9fba3924 | 196 | } |
frank26080115 | 0:bf7b9fba3924 | 197 | /*********************************************************************//** |
frank26080115 | 0:bf7b9fba3924 | 198 | * @brief Calculate CRC-7 as required by SD specification |
frank26080115 | 0:bf7b9fba3924 | 199 | * @param[in] - old_crc: 0x00 to start new CRC |
frank26080115 | 0:bf7b9fba3924 | 200 | * or value from previous call to continue. |
frank26080115 | 0:bf7b9fba3924 | 201 | * - data: data byte to add to CRC computation |
frank26080115 | 0:bf7b9fba3924 | 202 | * @return CRC-7 checksum which MUST be augmented by crc_7augment() before used |
frank26080115 | 0:bf7b9fba3924 | 203 | **********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 204 | uint8_t crc_7(uint8_t old_crc, uint8_t data) |
frank26080115 | 0:bf7b9fba3924 | 205 | { |
frank26080115 | 0:bf7b9fba3924 | 206 | uint8_t new_crc,x; |
frank26080115 | 0:bf7b9fba3924 | 207 | |
frank26080115 | 0:bf7b9fba3924 | 208 | new_crc = old_crc; |
frank26080115 | 0:bf7b9fba3924 | 209 | for (x = 7; x >= 0; x--) { |
frank26080115 | 0:bf7b9fba3924 | 210 | new_crc <<= 1; |
frank26080115 | 0:bf7b9fba3924 | 211 | new_crc |= GETBIT(data,x); |
frank26080115 | 0:bf7b9fba3924 | 212 | if (GETBIT(new_crc, 7) == 1) { |
frank26080115 | 0:bf7b9fba3924 | 213 | new_crc ^= 0x89; /*CRC-7's polynomial is x^7 + x^3 + 1*/ |
frank26080115 | 0:bf7b9fba3924 | 214 | } |
frank26080115 | 0:bf7b9fba3924 | 215 | if(x==0) break; |
frank26080115 | 0:bf7b9fba3924 | 216 | } |
frank26080115 | 0:bf7b9fba3924 | 217 | return new_crc; |
frank26080115 | 0:bf7b9fba3924 | 218 | } |
frank26080115 | 0:bf7b9fba3924 | 219 | /*********************************************************************//** |
frank26080115 | 0:bf7b9fba3924 | 220 | * @brief Provides the zero-padding final step to CRC-7 |
frank26080115 | 0:bf7b9fba3924 | 221 | * @param[in] - old_crc: value from last crc_7()call |
frank26080115 | 0:bf7b9fba3924 | 222 | * @return Finalized CRC-7 checksum |
frank26080115 | 0:bf7b9fba3924 | 223 | **********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 224 | uint8_t crc_7final(uint8_t old_crc) |
frank26080115 | 0:bf7b9fba3924 | 225 | { |
frank26080115 | 0:bf7b9fba3924 | 226 | uint8_t new_crc,x; |
frank26080115 | 0:bf7b9fba3924 | 227 | |
frank26080115 | 0:bf7b9fba3924 | 228 | new_crc = old_crc; |
frank26080115 | 0:bf7b9fba3924 | 229 | for (x = 0; x < 7; x++) { |
frank26080115 | 0:bf7b9fba3924 | 230 | new_crc <<= 1; |
frank26080115 | 0:bf7b9fba3924 | 231 | if (GETBIT(new_crc, 7) == 1) { |
frank26080115 | 0:bf7b9fba3924 | 232 | new_crc ^= 0x89; /*CRC-7's polynomial is x^7 + x^3 + 1*/ |
frank26080115 | 0:bf7b9fba3924 | 233 | } |
frank26080115 | 0:bf7b9fba3924 | 234 | } |
frank26080115 | 0:bf7b9fba3924 | 235 | return new_crc; |
frank26080115 | 0:bf7b9fba3924 | 236 | } |
frank26080115 | 0:bf7b9fba3924 | 237 | /*********************************************************************//** |
frank26080115 | 0:bf7b9fba3924 | 238 | * @brief Send/receive data over SPI bus |
frank26080115 | 0:bf7b9fba3924 | 239 | * @param[in] - tx_buf: pointer to transmit buffer. |
frank26080115 | 0:bf7b9fba3924 | 240 | * NULL if send 0xFF. |
frank26080115 | 0:bf7b9fba3924 | 241 | * - rx_buf: pointer to receive buffer |
frank26080115 | 0:bf7b9fba3924 | 242 | * NULL if nothing to receive. |
frank26080115 | 0:bf7b9fba3924 | 243 | * - length: number of data to send or receive |
frank26080115 | 0:bf7b9fba3924 | 244 | * @return the actual data sent or received. |
frank26080115 | 0:bf7b9fba3924 | 245 | **********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 246 | uint32_t SD_SendReceiveData_Polling(void* tx_buf, void* rx_buf, uint32_t length) |
frank26080115 | 0:bf7b9fba3924 | 247 | { |
frank26080115 | 0:bf7b9fba3924 | 248 | //uint16_t i; |
frank26080115 | 0:bf7b9fba3924 | 249 | |
frank26080115 | 0:bf7b9fba3924 | 250 | CS_Force(0); |
frank26080115 | 0:bf7b9fba3924 | 251 | //for(i=0;i<1000;i++); |
frank26080115 | 0:bf7b9fba3924 | 252 | |
frank26080115 | 0:bf7b9fba3924 | 253 | xferConfig.tx_data = tx_buf; |
frank26080115 | 0:bf7b9fba3924 | 254 | xferConfig.rx_data = rx_buf; |
frank26080115 | 0:bf7b9fba3924 | 255 | xferConfig.length = length; |
frank26080115 | 0:bf7b9fba3924 | 256 | SPI_ReadWrite(LPC_SPI, &xferConfig, SPI_TRANSFER_POLLING); |
frank26080115 | 0:bf7b9fba3924 | 257 | |
frank26080115 | 0:bf7b9fba3924 | 258 | //for(i=0;i<1000;i++); |
frank26080115 | 0:bf7b9fba3924 | 259 | CS_Force(1); |
frank26080115 | 0:bf7b9fba3924 | 260 | return xferConfig.counter; |
frank26080115 | 0:bf7b9fba3924 | 261 | } |
frank26080115 | 0:bf7b9fba3924 | 262 | /*********************************************************************//** |
frank26080115 | 0:bf7b9fba3924 | 263 | * @brief Send command to SD card |
frank26080115 | 0:bf7b9fba3924 | 264 | * @param[in] - cmd: SD command code |
frank26080115 | 0:bf7b9fba3924 | 265 | * - arg: pointer to array of 4x8 bytes, argument of command |
frank26080115 | 0:bf7b9fba3924 | 266 | * @return n/a |
frank26080115 | 0:bf7b9fba3924 | 267 | **********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 268 | void SD_SendCommand(uint8_t cmd, uint8_t *arg) |
frank26080115 | 0:bf7b9fba3924 | 269 | { |
frank26080115 | 0:bf7b9fba3924 | 270 | uint8_t crc = 0x00; |
frank26080115 | 0:bf7b9fba3924 | 271 | |
frank26080115 | 0:bf7b9fba3924 | 272 | /* First byte has framing bits and command */ |
frank26080115 | 0:bf7b9fba3924 | 273 | sd_cmd_buf[0] = 0x40 | (cmd & 0x3f); |
frank26080115 | 0:bf7b9fba3924 | 274 | sd_cmd_buf[1] = arg[0]; |
frank26080115 | 0:bf7b9fba3924 | 275 | sd_cmd_buf[2] = arg[1]; |
frank26080115 | 0:bf7b9fba3924 | 276 | sd_cmd_buf[3] = arg[2]; |
frank26080115 | 0:bf7b9fba3924 | 277 | sd_cmd_buf[4] = arg[3]; |
frank26080115 | 0:bf7b9fba3924 | 278 | //calculate CRC |
frank26080115 | 0:bf7b9fba3924 | 279 | crc = crc_7(crc, sd_cmd_buf[0]);//start new crc-7 |
frank26080115 | 0:bf7b9fba3924 | 280 | crc = crc_7(crc, sd_cmd_buf[1]); |
frank26080115 | 0:bf7b9fba3924 | 281 | crc = crc_7(crc, sd_cmd_buf[2]); |
frank26080115 | 0:bf7b9fba3924 | 282 | crc = crc_7(crc, sd_cmd_buf[3]); |
frank26080115 | 0:bf7b9fba3924 | 283 | crc = crc_7(crc, sd_cmd_buf[4]); |
frank26080115 | 0:bf7b9fba3924 | 284 | crc = crc_7final(crc); |
frank26080115 | 0:bf7b9fba3924 | 285 | sd_cmd_buf[5] = (crc << 1) | 0x01;//stop bit |
frank26080115 | 0:bf7b9fba3924 | 286 | |
frank26080115 | 0:bf7b9fba3924 | 287 | SD_SendReceiveData_Polling(sd_cmd_buf,NULL,SD_CMD_BLOCK_LENGTH); |
frank26080115 | 0:bf7b9fba3924 | 288 | } |
frank26080115 | 0:bf7b9fba3924 | 289 | /*********************************************************************//** |
frank26080115 | 0:bf7b9fba3924 | 290 | * @brief Wait for SD card R1 response |
frank26080115 | 0:bf7b9fba3924 | 291 | * @param[in] - buffer: pointer to receive buffer |
frank26080115 | 0:bf7b9fba3924 | 292 | * - length: length of receive data, must equal 1+actual length of data |
frank26080115 | 0:bf7b9fba3924 | 293 | * length = 0 if receive R1 only |
frank26080115 | 0:bf7b9fba3924 | 294 | * - timeout: timeout for retry |
frank26080115 | 0:bf7b9fba3924 | 295 | * @return error code |
frank26080115 | 0:bf7b9fba3924 | 296 | **********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 297 | sd_error SD_WaitR1(uint8_t *buffer, uint32_t length, uint32_t timeout) |
frank26080115 | 0:bf7b9fba3924 | 298 | { |
frank26080115 | 0:bf7b9fba3924 | 299 | uint32_t j; |
frank26080115 | 0:bf7b9fba3924 | 300 | uint8_t dummy[2]; |
frank26080115 | 0:bf7b9fba3924 | 301 | uint8_t wait_idle; |
frank26080115 | 0:bf7b9fba3924 | 302 | |
frank26080115 | 0:bf7b9fba3924 | 303 | /* No null pointers allowed */ |
frank26080115 | 0:bf7b9fba3924 | 304 | if (buffer == NULL) return SD_CMD_BAD_PARAMETER; |
frank26080115 | 0:bf7b9fba3924 | 305 | |
frank26080115 | 0:bf7b9fba3924 | 306 | /* Wait for start bit on R1 */ |
frank26080115 | 0:bf7b9fba3924 | 307 | j=0;dummy[0]=0xFF; |
frank26080115 | 0:bf7b9fba3924 | 308 | while (GETBIT(dummy[0],7) == 1) |
frank26080115 | 0:bf7b9fba3924 | 309 | { |
frank26080115 | 0:bf7b9fba3924 | 310 | if (j>timeout)return SD_ERROR_TIMEOUT; |
frank26080115 | 0:bf7b9fba3924 | 311 | dummy[0]=0x00; |
frank26080115 | 0:bf7b9fba3924 | 312 | SD_SendReceiveData_Polling(NULL,dummy,1); |
frank26080115 | 0:bf7b9fba3924 | 313 | j++; |
frank26080115 | 0:bf7b9fba3924 | 314 | } |
frank26080115 | 0:bf7b9fba3924 | 315 | *buffer=dummy[0];//store R1 |
frank26080115 | 0:bf7b9fba3924 | 316 | if (length > 0)//read followed data |
frank26080115 | 0:bf7b9fba3924 | 317 | { |
frank26080115 | 0:bf7b9fba3924 | 318 | /* Wait for start token on data portion, if any */ |
frank26080115 | 0:bf7b9fba3924 | 319 | dummy[0] = 0xff;j = 0; |
frank26080115 | 0:bf7b9fba3924 | 320 | while (dummy[0] != 0xfe) |
frank26080115 | 0:bf7b9fba3924 | 321 | { |
frank26080115 | 0:bf7b9fba3924 | 322 | if (j > timeout)return SD_ERROR_TIMEOUT; |
frank26080115 | 0:bf7b9fba3924 | 323 | dummy[0]=0x00; |
frank26080115 | 0:bf7b9fba3924 | 324 | SD_SendReceiveData_Polling(NULL,dummy,1); |
frank26080115 | 0:bf7b9fba3924 | 325 | if ((dummy[0] != 0xff) && (dummy[0] != 0xfe)) // not idle or start token? |
frank26080115 | 0:bf7b9fba3924 | 326 | { |
frank26080115 | 0:bf7b9fba3924 | 327 | return SD_ERROR_TOKEN; |
frank26080115 | 0:bf7b9fba3924 | 328 | } |
frank26080115 | 0:bf7b9fba3924 | 329 | j++; |
frank26080115 | 0:bf7b9fba3924 | 330 | } |
frank26080115 | 0:bf7b9fba3924 | 331 | /* Read all bytes */ |
frank26080115 | 0:bf7b9fba3924 | 332 | SD_SendReceiveData_Polling(NULL,(buffer+1),(length - 1)); |
frank26080115 | 0:bf7b9fba3924 | 333 | } |
frank26080115 | 0:bf7b9fba3924 | 334 | /* Some more bit clocks to finish internal SD operations */ |
frank26080115 | 0:bf7b9fba3924 | 335 | dummy[0]=0x00;wait_idle=0; |
frank26080115 | 0:bf7b9fba3924 | 336 | while((dummy[0]!=0xff)&&(wait_idle<20)) |
frank26080115 | 0:bf7b9fba3924 | 337 | { |
frank26080115 | 0:bf7b9fba3924 | 338 | dummy[0]=0x00; |
frank26080115 | 0:bf7b9fba3924 | 339 | SD_SendReceiveData_Polling(NULL,dummy,1); |
frank26080115 | 0:bf7b9fba3924 | 340 | for(j=0;j<1000;j++); |
frank26080115 | 0:bf7b9fba3924 | 341 | wait_idle++; |
frank26080115 | 0:bf7b9fba3924 | 342 | } |
frank26080115 | 0:bf7b9fba3924 | 343 | if(wait_idle>=20) return SD_ERROR_BUS_NOT_IDLE; |
frank26080115 | 0:bf7b9fba3924 | 344 | return SD_OK; |
frank26080115 | 0:bf7b9fba3924 | 345 | } |
frank26080115 | 0:bf7b9fba3924 | 346 | /*********************************************************************//** |
frank26080115 | 0:bf7b9fba3924 | 347 | * @brief Wait for SD card idle |
frank26080115 | 0:bf7b9fba3924 | 348 | * @param[in] - num_char: number characters (8 bits clock) to wait |
frank26080115 | 0:bf7b9fba3924 | 349 | * @return device already in idle state or need more time |
frank26080115 | 0:bf7b9fba3924 | 350 | **********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 351 | sd_error SD_WaitDeviceIdle(uint32_t num_char) |
frank26080115 | 0:bf7b9fba3924 | 352 | { |
frank26080115 | 0:bf7b9fba3924 | 353 | uint8_t dummy[2]={0,0}; |
frank26080115 | 0:bf7b9fba3924 | 354 | uint32_t i=0; |
frank26080115 | 0:bf7b9fba3924 | 355 | |
frank26080115 | 0:bf7b9fba3924 | 356 | while ((i < num_char) && (dummy[0] != 0xff)) |
frank26080115 | 0:bf7b9fba3924 | 357 | { |
frank26080115 | 0:bf7b9fba3924 | 358 | dummy[0]=0x00; |
frank26080115 | 0:bf7b9fba3924 | 359 | SD_SendReceiveData_Polling(NULL,dummy,1); |
frank26080115 | 0:bf7b9fba3924 | 360 | if (dummy[0] == 0xff) |
frank26080115 | 0:bf7b9fba3924 | 361 | { |
frank26080115 | 0:bf7b9fba3924 | 362 | dummy[0]= 0x00; |
frank26080115 | 0:bf7b9fba3924 | 363 | SD_SendReceiveData_Polling(NULL,dummy,1); |
frank26080115 | 0:bf7b9fba3924 | 364 | if (dummy[0] == 0xff) |
frank26080115 | 0:bf7b9fba3924 | 365 | { |
frank26080115 | 0:bf7b9fba3924 | 366 | dummy[0]= 0x00; |
frank26080115 | 0:bf7b9fba3924 | 367 | SD_SendReceiveData_Polling(NULL,dummy,1); |
frank26080115 | 0:bf7b9fba3924 | 368 | } |
frank26080115 | 0:bf7b9fba3924 | 369 | } |
frank26080115 | 0:bf7b9fba3924 | 370 | i++; |
frank26080115 | 0:bf7b9fba3924 | 371 | } |
frank26080115 | 0:bf7b9fba3924 | 372 | if (dummy[0] != 0xff)return SD_ERROR_TIMEOUT; |
frank26080115 | 0:bf7b9fba3924 | 373 | |
frank26080115 | 0:bf7b9fba3924 | 374 | return SD_OK; |
frank26080115 | 0:bf7b9fba3924 | 375 | } |
frank26080115 | 0:bf7b9fba3924 | 376 | /*********************************************************************//** |
frank26080115 | 0:bf7b9fba3924 | 377 | * @brief Initialize SD card in SPI mode |
frank26080115 | 0:bf7b9fba3924 | 378 | * @param[in] - retries: number retry time |
frank26080115 | 0:bf7b9fba3924 | 379 | * @return initialization successful or terminated with specific error code |
frank26080115 | 0:bf7b9fba3924 | 380 | **********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 381 | sd_error SD_Init(uint8_t retries) |
frank26080115 | 0:bf7b9fba3924 | 382 | { |
frank26080115 | 0:bf7b9fba3924 | 383 | uint8_t rxdata,errors; |
frank26080115 | 0:bf7b9fba3924 | 384 | uint8_t SD_arg[4]={0,0,0,0}; |
frank26080115 | 0:bf7b9fba3924 | 385 | uint16_t i; |
frank26080115 | 0:bf7b9fba3924 | 386 | |
frank26080115 | 0:bf7b9fba3924 | 387 | // initialize SPI configuration structure to default |
frank26080115 | 0:bf7b9fba3924 | 388 | SPI_ConfigStructInit(&SPI_ConfigStruct); |
frank26080115 | 0:bf7b9fba3924 | 389 | // Initialize SPI peripheral with parameter given in structure above |
frank26080115 | 0:bf7b9fba3924 | 390 | SPI_Init(LPC_SPI, &SPI_ConfigStruct); |
frank26080115 | 0:bf7b9fba3924 | 391 | // Initialize /CS pin to GPIO function |
frank26080115 | 0:bf7b9fba3924 | 392 | CS_Init(); |
frank26080115 | 0:bf7b9fba3924 | 393 | // check for SD card insertion |
frank26080115 | 0:bf7b9fba3924 | 394 | _DBG("\n\rPlease plug-in SD card!"); |
frank26080115 | 0:bf7b9fba3924 | 395 | while(SD_GetCardConnectStatus()==SD_DISCONNECTED); |
frank26080115 | 0:bf7b9fba3924 | 396 | _DBG("...Connected!\n\r"); |
frank26080115 | 0:bf7b9fba3924 | 397 | // Wait for bus idle |
frank26080115 | 0:bf7b9fba3924 | 398 | if(SD_WaitDeviceIdle(160) != SD_OK) return SD_ERROR_BUS_NOT_IDLE; |
frank26080115 | 0:bf7b9fba3924 | 399 | _DBG("Initialize SD card in SPI mode..."); |
frank26080115 | 0:bf7b9fba3924 | 400 | |
frank26080115 | 0:bf7b9fba3924 | 401 | errors = 0; |
frank26080115 | 0:bf7b9fba3924 | 402 | /* Send the CMD0_GO_IDLE_STATE while CS is asserted */ |
frank26080115 | 0:bf7b9fba3924 | 403 | /* This signals the SD card to fall back to SPI mode */ |
frank26080115 | 0:bf7b9fba3924 | 404 | while(errors < retries) |
frank26080115 | 0:bf7b9fba3924 | 405 | { |
frank26080115 | 0:bf7b9fba3924 | 406 | SD_SendCommand(CMD0_GO_IDLE_STATE, SD_arg); |
frank26080115 | 0:bf7b9fba3924 | 407 | if(SD_WaitR1(&rxdata,0,1000)!= SD_OK) |
frank26080115 | 0:bf7b9fba3924 | 408 | { |
frank26080115 | 0:bf7b9fba3924 | 409 | errors++; |
frank26080115 | 0:bf7b9fba3924 | 410 | continue; |
frank26080115 | 0:bf7b9fba3924 | 411 | } |
frank26080115 | 0:bf7b9fba3924 | 412 | if(rxdata != R1_IDLE) |
frank26080115 | 0:bf7b9fba3924 | 413 | { |
frank26080115 | 0:bf7b9fba3924 | 414 | errors++; |
frank26080115 | 0:bf7b9fba3924 | 415 | continue; |
frank26080115 | 0:bf7b9fba3924 | 416 | } |
frank26080115 | 0:bf7b9fba3924 | 417 | else break; |
frank26080115 | 0:bf7b9fba3924 | 418 | } |
frank26080115 | 0:bf7b9fba3924 | 419 | if(errors >= retries)return SD_ERROR_CMD0; |
frank26080115 | 0:bf7b9fba3924 | 420 | |
frank26080115 | 0:bf7b9fba3924 | 421 | /* Check if the card is not MMC */ |
frank26080115 | 0:bf7b9fba3924 | 422 | /* Start its internal initialization process */ |
frank26080115 | 0:bf7b9fba3924 | 423 | while(1) |
frank26080115 | 0:bf7b9fba3924 | 424 | { |
frank26080115 | 0:bf7b9fba3924 | 425 | SD_SendCommand(CMD55_APP_CMD, SD_arg); |
frank26080115 | 0:bf7b9fba3924 | 426 | if(SD_WaitR1(&rxdata,0,1000)!= SD_OK) return SD_ERROR_CMD55; |
frank26080115 | 0:bf7b9fba3924 | 427 | |
frank26080115 | 0:bf7b9fba3924 | 428 | SD_SendCommand(ACMD41_SEND_OP_COND, SD_arg); |
frank26080115 | 0:bf7b9fba3924 | 429 | SD_WaitR1(&rxdata,0,1000); |
frank26080115 | 0:bf7b9fba3924 | 430 | if (rxdata & R1_IDLE) //in_idle_state = 1 |
frank26080115 | 0:bf7b9fba3924 | 431 | for (i = 0; i < 1000; i++); /* wait for a while */ |
frank26080115 | 0:bf7b9fba3924 | 432 | else break; //in_idle_state=0 --> ready |
frank26080115 | 0:bf7b9fba3924 | 433 | } |
frank26080115 | 0:bf7b9fba3924 | 434 | /* Enable CRC */ |
frank26080115 | 0:bf7b9fba3924 | 435 | SD_arg[3] = 0x01; |
frank26080115 | 0:bf7b9fba3924 | 436 | SD_SendCommand(CMD59_CRC_ON_OFF, SD_arg); |
frank26080115 | 0:bf7b9fba3924 | 437 | if(SD_WaitR1(&rxdata,0,1000)!= SD_OK) return SD_ERROR_CMD59; |
frank26080115 | 0:bf7b9fba3924 | 438 | if(rxdata != R1_NOERROR) return SD_ERROR_CMD59; |
frank26080115 | 0:bf7b9fba3924 | 439 | |
frank26080115 | 0:bf7b9fba3924 | 440 | return SD_OK; |
frank26080115 | 0:bf7b9fba3924 | 441 | } |
frank26080115 | 0:bf7b9fba3924 | 442 | /*********************************************************************//** |
frank26080115 | 0:bf7b9fba3924 | 443 | * @brief Get SD card's CID register |
frank26080115 | 0:bf7b9fba3924 | 444 | * @param[in] none |
frank26080115 | 0:bf7b9fba3924 | 445 | * @return OK or NG |
frank26080115 | 0:bf7b9fba3924 | 446 | * OK: the returned data from SD card is stored in sd_data_buf |
frank26080115 | 0:bf7b9fba3924 | 447 | **********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 448 | sd_error SD_GetCID(void) |
frank26080115 | 0:bf7b9fba3924 | 449 | { |
frank26080115 | 0:bf7b9fba3924 | 450 | uint8_t SD_arg[4]={0,0,0,0}; |
frank26080115 | 0:bf7b9fba3924 | 451 | |
frank26080115 | 0:bf7b9fba3924 | 452 | SD_SendCommand(CMD10_SEND_CID, SD_arg); |
frank26080115 | 0:bf7b9fba3924 | 453 | if(SD_WaitR1(sd_data_buf,18,1000)!= SD_OK) return SD_NG; |
frank26080115 | 0:bf7b9fba3924 | 454 | if(sd_data_buf[0]!= R1_NOERROR) return SD_NG; |
frank26080115 | 0:bf7b9fba3924 | 455 | return SD_OK; |
frank26080115 | 0:bf7b9fba3924 | 456 | } |
frank26080115 | 0:bf7b9fba3924 | 457 | /*-------------------------MAIN FUNCTION------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 458 | /*********************************************************************//** |
frank26080115 | 0:bf7b9fba3924 | 459 | * @brief c_entry: Main SPI program body |
frank26080115 | 0:bf7b9fba3924 | 460 | * @param[in] None |
frank26080115 | 0:bf7b9fba3924 | 461 | * @return int |
frank26080115 | 0:bf7b9fba3924 | 462 | **********************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 463 | int c_entry(void) |
frank26080115 | 0:bf7b9fba3924 | 464 | { |
frank26080115 | 0:bf7b9fba3924 | 465 | PINSEL_CFG_Type PinCfg; |
frank26080115 | 0:bf7b9fba3924 | 466 | sd_error sd_status; |
frank26080115 | 0:bf7b9fba3924 | 467 | uint8_t i; |
frank26080115 | 0:bf7b9fba3924 | 468 | uint8_t tem8; |
frank26080115 | 0:bf7b9fba3924 | 469 | uint32_t tem32; |
frank26080115 | 0:bf7b9fba3924 | 470 | /* |
frank26080115 | 0:bf7b9fba3924 | 471 | * Initialize SPI pin connect |
frank26080115 | 0:bf7b9fba3924 | 472 | * P0.15 - SCK; |
frank26080115 | 0:bf7b9fba3924 | 473 | * P0.16 - SSEL - used as GPIO |
frank26080115 | 0:bf7b9fba3924 | 474 | * P0.17 - MISO |
frank26080115 | 0:bf7b9fba3924 | 475 | * P0.18 - MOSI |
frank26080115 | 0:bf7b9fba3924 | 476 | */ |
frank26080115 | 0:bf7b9fba3924 | 477 | PinCfg.Funcnum = 3; |
frank26080115 | 0:bf7b9fba3924 | 478 | PinCfg.OpenDrain = 0; |
frank26080115 | 0:bf7b9fba3924 | 479 | PinCfg.Pinmode = 0; |
frank26080115 | 0:bf7b9fba3924 | 480 | PinCfg.Portnum = 0; |
frank26080115 | 0:bf7b9fba3924 | 481 | PinCfg.Pinnum = 15; |
frank26080115 | 0:bf7b9fba3924 | 482 | PINSEL_ConfigPin(&PinCfg); |
frank26080115 | 0:bf7b9fba3924 | 483 | PinCfg.Pinnum = 17; |
frank26080115 | 0:bf7b9fba3924 | 484 | PINSEL_ConfigPin(&PinCfg); |
frank26080115 | 0:bf7b9fba3924 | 485 | PinCfg.Pinnum = 18; |
frank26080115 | 0:bf7b9fba3924 | 486 | PINSEL_ConfigPin(&PinCfg); |
frank26080115 | 0:bf7b9fba3924 | 487 | PinCfg.Pinnum = 16; |
frank26080115 | 0:bf7b9fba3924 | 488 | PinCfg.Funcnum = 0; |
frank26080115 | 0:bf7b9fba3924 | 489 | PINSEL_ConfigPin(&PinCfg); |
frank26080115 | 0:bf7b9fba3924 | 490 | //Initialize SD card detection pin P4.29 |
frank26080115 | 0:bf7b9fba3924 | 491 | PinCfg.Portnum = 4; |
frank26080115 | 0:bf7b9fba3924 | 492 | PinCfg.Pinnum = 29; |
frank26080115 | 0:bf7b9fba3924 | 493 | PinCfg.Funcnum = 0;//GPIO function |
frank26080115 | 0:bf7b9fba3924 | 494 | PINSEL_ConfigPin(&PinCfg); |
frank26080115 | 0:bf7b9fba3924 | 495 | GPIO_SetDir(SD_DETECT_PORTNUM, (1<<SD_DETECT_PINNUM), 0);//input |
frank26080115 | 0:bf7b9fba3924 | 496 | |
frank26080115 | 0:bf7b9fba3924 | 497 | /* Initialize debug via UART0 |
frank26080115 | 0:bf7b9fba3924 | 498 | * 115200bps |
frank26080115 | 0:bf7b9fba3924 | 499 | * 8 data bit |
frank26080115 | 0:bf7b9fba3924 | 500 | * No parity |
frank26080115 | 0:bf7b9fba3924 | 501 | * 1 stop bit |
frank26080115 | 0:bf7b9fba3924 | 502 | * No flow control |
frank26080115 | 0:bf7b9fba3924 | 503 | */ |
frank26080115 | 0:bf7b9fba3924 | 504 | debug_frmwrk_init(); |
frank26080115 | 0:bf7b9fba3924 | 505 | |
frank26080115 | 0:bf7b9fba3924 | 506 | // print welcome screen |
frank26080115 | 0:bf7b9fba3924 | 507 | print_menu(); |
frank26080115 | 0:bf7b9fba3924 | 508 | |
frank26080115 | 0:bf7b9fba3924 | 509 | //initialize SD card |
frank26080115 | 0:bf7b9fba3924 | 510 | sd_status = SD_Init(10); |
frank26080115 | 0:bf7b9fba3924 | 511 | switch(sd_status) |
frank26080115 | 0:bf7b9fba3924 | 512 | { |
frank26080115 | 0:bf7b9fba3924 | 513 | case SD_ERROR_CMD0: |
frank26080115 | 0:bf7b9fba3924 | 514 | _DBG("Fail CMD0\n\r"); |
frank26080115 | 0:bf7b9fba3924 | 515 | break; |
frank26080115 | 0:bf7b9fba3924 | 516 | case SD_ERROR_CMD55: |
frank26080115 | 0:bf7b9fba3924 | 517 | _DBG("Fail CMD55\n\r"); |
frank26080115 | 0:bf7b9fba3924 | 518 | break; |
frank26080115 | 0:bf7b9fba3924 | 519 | case SD_ERROR_ACMD41: |
frank26080115 | 0:bf7b9fba3924 | 520 | _DBG("Fail ACMD41\n\r"); |
frank26080115 | 0:bf7b9fba3924 | 521 | break; |
frank26080115 | 0:bf7b9fba3924 | 522 | case SD_ERROR_CMD59: |
frank26080115 | 0:bf7b9fba3924 | 523 | _DBG("Fail CMD59\n\r"); |
frank26080115 | 0:bf7b9fba3924 | 524 | break; |
frank26080115 | 0:bf7b9fba3924 | 525 | case SD_ERROR_BUS_NOT_IDLE: |
frank26080115 | 0:bf7b9fba3924 | 526 | _DBG("Fail...Device is not in idle state.\n\r"); |
frank26080115 | 0:bf7b9fba3924 | 527 | break; |
frank26080115 | 0:bf7b9fba3924 | 528 | case SD_OK: |
frank26080115 | 0:bf7b9fba3924 | 529 | _DBG("Done!\n\r"); |
frank26080115 | 0:bf7b9fba3924 | 530 | break; |
frank26080115 | 0:bf7b9fba3924 | 531 | default: |
frank26080115 | 0:bf7b9fba3924 | 532 | _DBG("Fail\n\r"); |
frank26080115 | 0:bf7b9fba3924 | 533 | break; |
frank26080115 | 0:bf7b9fba3924 | 534 | } |
frank26080115 | 0:bf7b9fba3924 | 535 | if(sd_status == SD_OK) |
frank26080115 | 0:bf7b9fba3924 | 536 | { |
frank26080115 | 0:bf7b9fba3924 | 537 | //Clear receive buffer |
frank26080115 | 0:bf7b9fba3924 | 538 | for(i=1;i<18;i++)sd_data_buf[i]=0; |
frank26080115 | 0:bf7b9fba3924 | 539 | |
frank26080115 | 0:bf7b9fba3924 | 540 | _DBG("Reading SD card's CID register..."); |
frank26080115 | 0:bf7b9fba3924 | 541 | if(SD_GetCID()!= SD_OK) |
frank26080115 | 0:bf7b9fba3924 | 542 | { |
frank26080115 | 0:bf7b9fba3924 | 543 | _DBG("Fail\n\r"); |
frank26080115 | 0:bf7b9fba3924 | 544 | SPI_DeInit(LPC_SPI); |
frank26080115 | 0:bf7b9fba3924 | 545 | } |
frank26080115 | 0:bf7b9fba3924 | 546 | else |
frank26080115 | 0:bf7b9fba3924 | 547 | { |
frank26080115 | 0:bf7b9fba3924 | 548 | _DBG("Done!"); |
frank26080115 | 0:bf7b9fba3924 | 549 | _DBG("\n\rManufacture ID: ");_DBH(sd_data_buf[1]); |
frank26080115 | 0:bf7b9fba3924 | 550 | _DBG("\n\rApplication ID: ");_DBC(sd_data_buf[2]);_DBC(sd_data_buf[3]); |
frank26080115 | 0:bf7b9fba3924 | 551 | _DBG("\n\rProduct name: "); |
frank26080115 | 0:bf7b9fba3924 | 552 | for(i=4;i<9;i++) _DBC(sd_data_buf[i]); |
frank26080115 | 0:bf7b9fba3924 | 553 | _DBG("\n\rProduct revision: "); |
frank26080115 | 0:bf7b9fba3924 | 554 | tem8 = (sd_data_buf[9]&0xF0)>>4;_DBD(tem8); |
frank26080115 | 0:bf7b9fba3924 | 555 | _DBG("."); |
frank26080115 | 0:bf7b9fba3924 | 556 | tem8 = (sd_data_buf[9]&0x0F);_DBD(tem8); |
frank26080115 | 0:bf7b9fba3924 | 557 | _DBG("\n\rProduct serial number: "); |
frank26080115 | 0:bf7b9fba3924 | 558 | tem32= (sd_data_buf[13]<<24)|(sd_data_buf[12]<<16)| |
frank26080115 | 0:bf7b9fba3924 | 559 | (sd_data_buf[11]<<8)|(sd_data_buf[10]<<0); |
frank26080115 | 0:bf7b9fba3924 | 560 | _DBH32(tem32); |
frank26080115 | 0:bf7b9fba3924 | 561 | _DBG("\n\rManufacturing date: "); |
frank26080115 | 0:bf7b9fba3924 | 562 | tem8 = (sd_data_buf[15]&0x0F);_DBD(tem8); |
frank26080115 | 0:bf7b9fba3924 | 563 | _DBG("/"); |
frank26080115 | 0:bf7b9fba3924 | 564 | tem8 = ((sd_data_buf[14]&0x0F)<<4) | ((sd_data_buf[15]&0xF0)>>4); |
frank26080115 | 0:bf7b9fba3924 | 565 | _DBG("2");_DBD(tem8); |
frank26080115 | 0:bf7b9fba3924 | 566 | } |
frank26080115 | 0:bf7b9fba3924 | 567 | } |
frank26080115 | 0:bf7b9fba3924 | 568 | else |
frank26080115 | 0:bf7b9fba3924 | 569 | // DeInitialize SPI peripheral |
frank26080115 | 0:bf7b9fba3924 | 570 | SPI_DeInit(LPC_SPI); |
frank26080115 | 0:bf7b9fba3924 | 571 | /* Loop forever */ |
frank26080115 | 0:bf7b9fba3924 | 572 | while(1); |
frank26080115 | 0:bf7b9fba3924 | 573 | return 1; |
frank26080115 | 0:bf7b9fba3924 | 574 | } |
frank26080115 | 0:bf7b9fba3924 | 575 | |
frank26080115 | 0:bf7b9fba3924 | 576 | /* With ARM and GHS toolsets, the entry point is main() - this will |
frank26080115 | 0:bf7b9fba3924 | 577 | allow the linker to generate wrapper code to setup stacks, allocate |
frank26080115 | 0:bf7b9fba3924 | 578 | heap area, and initialize and copy code and data segments. For GNU |
frank26080115 | 0:bf7b9fba3924 | 579 | toolsets, the entry point is through __start() in the crt0_gnu.asm |
frank26080115 | 0:bf7b9fba3924 | 580 | file, and that startup code will setup stacks and data */ |
frank26080115 | 0:bf7b9fba3924 | 581 | int main(void) |
frank26080115 | 0:bf7b9fba3924 | 582 | { |
frank26080115 | 0:bf7b9fba3924 | 583 | return c_entry(); |
frank26080115 | 0:bf7b9fba3924 | 584 | } |
frank26080115 | 0:bf7b9fba3924 | 585 | |
frank26080115 | 0:bf7b9fba3924 | 586 | |
frank26080115 | 0:bf7b9fba3924 | 587 | #ifdef DEBUG |
frank26080115 | 0:bf7b9fba3924 | 588 | /******************************************************************************* |
frank26080115 | 0:bf7b9fba3924 | 589 | * @brief Reports the name of the source file and the source line number |
frank26080115 | 0:bf7b9fba3924 | 590 | * where the CHECK_PARAM error has occurred. |
frank26080115 | 0:bf7b9fba3924 | 591 | * @param[in] file Pointer to the source file name |
frank26080115 | 0:bf7b9fba3924 | 592 | * @param[in] line assert_param error line source number |
frank26080115 | 0:bf7b9fba3924 | 593 | * @return None |
frank26080115 | 0:bf7b9fba3924 | 594 | *******************************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 595 | void check_failed(uint8_t *file, uint32_t line) |
frank26080115 | 0:bf7b9fba3924 | 596 | { |
frank26080115 | 0:bf7b9fba3924 | 597 | /* User can add his own implementation to report the file name and line number, |
frank26080115 | 0:bf7b9fba3924 | 598 | ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ |
frank26080115 | 0:bf7b9fba3924 | 599 | |
frank26080115 | 0:bf7b9fba3924 | 600 | /* Infinite loop */ |
frank26080115 | 0:bf7b9fba3924 | 601 | while(1); |
frank26080115 | 0:bf7b9fba3924 | 602 | } |
frank26080115 | 0:bf7b9fba3924 | 603 | #endif |
frank26080115 | 0:bf7b9fba3924 | 604 | /* |
frank26080115 | 0:bf7b9fba3924 | 605 | * @} |
frank26080115 | 0:bf7b9fba3924 | 606 | */ |