Here are some standard definitions I use throughout this tutorial. You can modify them to suite your needs, but these seem to work fine for me. I modified the INTEGER.H file included in Chan’s library as follows:
/*-------------------------------------------*/ /* Integer type definitions for FatFs module */ /*-------------------------------------------*/ #ifndef _INTEGER /* These types must be 16-bit, 32-bit or larger integer */ typedef int INT; typedef unsigned int UINT; /* These types must be 8-bit integer */ typedef signed char CHAR; typedef unsigned char UCHAR; /* These types must be 16-bit integer */ typedef short SHORT; typedef unsigned short USHORT; /* These types must be 32-bit integer */ typedef long LONG; typedef unsigned long DWORD; #ifndef STANDARD_TYPES #define STANDARD_TYPES typedef unsigned char BYTE; typedef unsigned int WORD; typedef unsigned long ULONG; #endif /* Boolean type */ typedef enum { FALSE = 0, TRUE } BOOL; #define _INTEGER #endif
The following variable is global, and necessary for Chan’s Library
xdata WORD CardType; /* MMC = 0, SDCard v1 = 1, SDCard v2 = 2 */
These are specific to the SPI interface in my microcontroller. Again, you can modify them to suite your needs, and better match your hardware environment.
enum SPI_FREQUENCIES { kHz400, MHz1, MHz5, MHz10 }; /* =========================================================== */ /* Table 59. SPICON0: Control Register 0 */ /* (SFR D6h, Reset Value 00h) */ /* */ /* BIT SYMBOL R/W DEFINITION */ /* --- ------ --- ---------------------------------------- */ /* 7 -- - Reserved... */ /* 6 TE R/W T)ransmitter E)nable */ /* 0 = transmitter disabled, */ /* 1 = transmitter enabled */ /* 5 RE R/W R)eceiver E)nable */ /* 0 = receiver disabled, */ /* 1 = receiver enabled */ /* 4 SPIEN R/W SPI) E)nable */ /* 0 = entire SPI interface disabled, */ /* 1 = entire SPI interface enabled */ /* 3 SSEL R/W S)lave SEL)ection */ /* 0 = SPISEL output always '1', */ /* 1 = SPISEL output '0' during transfers */ /* 2 FLSB R/W F)irst LSB) */ /* 0 = transfer MSB first, */ /* 1 = transfer LSB first */ /* 1 SPO R/W S)ampling PO)larity */ /* 0 = Sample transfer data at falling edge */ /* of clock (SPICLK is '0' when idle) */ /* 1 = Sample transfer data at rising edge */ /* of clock (SPICLK is '1' when idle) */ /* 0 -- - Reserved... */ /* */ /* =========================================================== */ #define TE 0x40 #define RE 0x20 #define SPIEN 0x10 #define SSEL 0x08 // This feature is disabled in PDSoft... #define FLSB 0x04 #define SPO 0x02
The following table is used for setting the frequency of the SPI clock – This is definitely hardware specific. My system’s normal crystal frequency is 40.0Mhz, but this example uses a 22.1184Mhz crystal, so that’s why I setup this table. Also, the upsd3334D microcontroller is a 4-clocker, not a 12-clocker device, which means it takes only 4 clock cycles to execute a simple instruction, not 12 like a typical 8052. Your hardware will dictate the values you use as timer constants.
/* =========================================================== */ /* Table 61. SPICLKD: SPI Prescaler (Clock Divider) */ /* Register (SFR D2h, Reset Value 04h) */ /* based on frequency, the following are */ /* divisors for the SPI clock register */ /* =========================================================== */ #define SPI_FREQUENCY_10MHz 4 // Fastest: 10MHz @ 40MHz, and // 5.529MHz at 22.1184MHz #ifdef NORMAL_SPEED #define SPI_FREQUENCY_5MHz 8 // 5MHz #define SPI_FREQUENCY_1MHz 40 // 1MHz #define SPI_FREQUENCY_400KHz 100 // 400kHz #else #define SPI_FREQUENCY_5MHz 4 // 5.529MHz #define SPI_FREQUENCY_1MHz 20 // 1.105MHz #define SPI_FREQUENCY_400KHz 56 // 394.971kHz #endif /* =========================================================== */ /* Table 62. SPISTAT: SPI Interface Status Register */ /* (SFR D3h, Reset Value 02h) */ /* */ /* BIT SYMBOL R/W DEFINITION */ /* --- ------ --- -------------------------------------- */ /* 7 -- - Reserved... */ /* 6 -- - Reserved... */ /* 5 -- - Reserved... */ /* 4 BUSY R SPI Busy */ /* 0 = Transmit or Receive is completed */ /* 1 = Transmit or Receive is in process */ /* 3 TEISF R */ /* T)ransmission E)nd I)nterrupt S)ource F)lag */ /* 0 = Automatically resets to '0' */ /* when firmware reads this register */ /* 1 = Automatically sets to '1' */ /* when transmission end occurs */ /* 2 RORISF R */ /* R)eceive O)verrun I)nterrupt S)ource F)lag */ /* 0 = Automatically resets to '0' */ /* when firmware reads this register */ /* 1 = Automatically sets to '1' */ /* when receive overrun occurs */ /* 1 TISF R T)ransmission I)nterrupt S)ource F)lag */ /* 0 = Automatically resets to '0' */ /* when SPITDR is full */ /* (just after the SPITDR is written) */ /* 1 = Automatically sets to '1' */ /* when SPITDR is empty */ /* (just after BYTE loads from SPITDR into SPI shift register) */ /* 0 RISF R R)eception I)nterrupt S)ource F)lag */ /* 0 = Automatically resets to '0' */ /* when SPIRDR is empty */ /* (after the SPIRDR is read) */ /* 1 = Automatically sets to '1' */ /* when SPIRDR is full */ /* */ /* =========================================================== */ #define BUSY 0x10 #define TEISF 0x08 #define RORISF 0x04 #define TISF 0x02 #define RISF 0x01