This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP432P401R: MSP432 interface SDCard based on [MSP Classic Registers]

Part Number: MSP432P401R

Tool/software: Code Composer Studio

Hello people, I'am trying use a SDCARD only to regist data. All my project was made with "MSPClassic Registers", so I saw in the forum a Bluehash post, but was in CMSIS, in mode to satisfy my project I try to change some files. Now I have some problems to finish him there is someone who can help me?I need Something very simple, just confirm if the card is loaded or not and save data.  I am using the MSP432. But I not using the booster pack, its a simple SDcard shield,  this code have a LCD conection to made a simple debug.

Connections, for LCD and SDcard, PORT | PIN connections:

MSP432------------------>LCD          MSP432------------------>SDcard

J4                                                           JP2.6----------------------->D4            P1.5------------------>CLK              

P2.4----------------------->D5            P4.6------------------>CS/SS

P5.6----------------------->D6                 J2

P6.6----------------------->D7            P1.6------------------>MOSI

P2.3----------------------->E              P1.7------------------>MISO

P6.7----------------------->RS  

Files v.2:

3443.config.h



#include <stdint.h>
#include <stdbool.h>
#include "msp.h"
#include "diskio.h"
#include "pff.h"
#include "spi.h"




#define DELAY_100US() 	__delay_cycles(1600) 	/*(100us/(1/16MHz)) = 1600 TICKS*/
#define MMC_SEL 			!(P4->OUT & BIT6) 		/*CS STATUS  (TRUE:CS == LOW)*/
#define FORWARD(d) 0





/*DEFENITIONS TO MMC/SDC COMMAND*/
#define CMD0		(0x40+0)		/*GO_IDLE_STATE*/
#define CMD1		(0x40+1)		/*SEND_OP_COND (MMC)*/
#define CMD8		(0x40+8) 	/*SEND_IF_COND*/
#define CMD9		(0x40+9) 	/*SEND_CSD*/
#define CMD10	(0x40+10) 	/*SEND_CID*/
#define CMD12	(0x40+12) 	/*STOP_TRANSMISSION*/
#define CMD16	(0x40+16) 	/*SET_BLOCKLEN*/
#define CMD17	(0x40+17) 	/*READ_SINGLE_BLOCK*/
#define CMD18	(0x40+18) 	/*READ_MULTIPLE_BLOCK*/
#define CMD23	(0x40+23) 	/*SET_BLOCK_COUNT*/
#define CMD24	(0x40+24) 	/*WRITE_BLOCK*/
#define CMD25	(0x40+25) 	/*WRITE_MULTIPLE_BLOCK*/
#define CMD41	(0x40+41) 	/*APP_SEND_OP_COND (ACMD)*/
#define CMD55	(0x40+55) 	/*APP_CMD*/
#define CMD58	(0x40+58) 	/*READ_OCR*/

/*CARD TYPE FLAG'S (CARDTYPE)*/
#define CT_MMC		0X01			/*MMC VER 3*/
#define CT_SD1		0X02			/*SD VER 1*/
#define CT_SD2		0X04			/*SD VER 2*/
#define	CT_BLOCK 	0X08			/*BLOCK ADDRESSING*/

/*************************************************************
 * 				ASSERTS  THE CS OIN TO THE CARD 				*
 *************************************************************/

#define SELECT() 		P4->OUT &= ~BIT6 		/*CS = LOW*/
#define DESELECT() 		P4->OUT |= BIT6 			/*CS = HIGH*/

/*************************************************************
 * 					MODULE PRIVATE FUNCTIONS 				*
 *************************************************************/
static volatile DSTATUS Stat = STA_NOINIT; /*DISK STATUS*/

static volatile BYTE Timer1, Timer2; /*100Hz DECREMENT TIMMER*/

static BYTE CardType;/*B0:MMC, B1:SDC, B2:BLOCK ADDRESSING*/

static BYTE PowerFlag = 0;/*INDICATE IF "POWER" IS ON*/

/*************************************************************
 * 				TRANSMIT BYTE TO MMC VIA SPI 				*
 *************************************************************/
static void xmit_spi(BYTE dat){
	uint32_t ui32RcvDat = 0;

	/*SEND DATA*/
	SPI_transmitData(EUSCI_B0_BASE, dat);

	/*FLUSH DATA READ DURING THE WRITE*/
	ui32RcvDat = SPI_receiveData(EUSCI_B0_BASE);

	/*GET RID OF "VARIABLE SET, BUT UNUSED" WARNING*/

	ui32RcvDat =ui32RcvDat + 1;

}

/*************************************************************
 * 				 RECEIVE BYTE TO MMC VIA SPI 				*
 *************************************************************/

static BYTE rcvr_spi(void){
	uint32_t ui32RcvDat;

	/*SEND A DUMMY*/
	SPI_transmitData(EUSCI_B0_BASE, 0XFF);

	ui32RcvDat = SPI_receiveData(EUSCI_B0_BASE); //^M

	return (BYTE)ui32RcvDat;

}

static void rcvr_spi_m(BYTE *dst){

	*dst = rcvr_spi();
}

/*************************************************************
 * 				  WAIT FOR THE CARD READY 					*
 *************************************************************/
static BYTE wait_ready(void){
	BYTE res;
	Timer2 = 50; /*WAIT FOR TIMEOUT OF 500ms*/
	rcvr_spi();
	do
		res = rcvr_spi();

	while((res!=0xFF) && Timer2);

	return res;
}

/*************************************************************
 *SEND 80 OR SO CLOCK TRANSITIONS WITH CS AND DI HELD HIGH 	*
 *THIS IS REQUIRED AFTER CARD POWER UO TO GET IT INTO SPI		*
 *MODE														*
 *************************************************************/

static void send_initial_clock_train (void){
	unsigned int i;

	uint32_t ui32Dat = 0;

	/*ENSURE CS IS HELD HIGH*/
	DESELECT();

	for (i = 0;i < 10;i++){


		/*SEND DATA*/
			SPI_transmitData(EUSCI_B0_BASE, 0); // primer test to prueba de inicio de memoria


			ui32Dat = SPI_receiveData(EUSCI_B0_BASE); // Inicializando la variable
		/*GET RID OF "VARIABLE SET, BUT UNUSED" WARNING*/
		ui32Dat = ui32Dat + 1;

	}

}
/*************************************************************
 * 			POWER CONTROL (PLANTAFORM DEPENDENT) 			*
 *************************************************************/
/*WHEN THE TARGET SYSTEM DOES THE SUPPORT SOCKET POWER CONTROL,
 *THERE IS NOTHING TO DO IN THESE FUNCTIONS AND CHECK_POWER
 *THERE ALWAYS RETURNS 1*/

static void power_on(void){

	/*SET DI AND CS HIGH AND MORE THAN 74 PULSES TO SLCK FOR THE CARD
	 * TO BE ABLE TO ACCEPT A NATIVE COMMAND*/
	send_initial_clock_train();

	PowerFlag =	1;
}

/*SET THE SSI SPEED TO THE MAX SETTING*/

static void set_max_speed(void){	//^M

}

static void power_off(void){
	PowerFlag = 0;
}

/*SOCKET POWER STATE: 0 = OFF, 1 = ON*/
static int chk_power(void){
	return PowerFlag;
}
/*************************************************************
 * 				RECEIVE A DATA PACKET FROM MMC 				*
 *************************************************************/

/*DATA BUFFER TO STORE RECEIVED DATA
 *BYTE COUNT (MUST BE EVEN NUMBER)*/
static BOOL rcvr_datablock(BYTE *buff, UINT btr){
	BYTE token;
	/*WAIT FOR DATA PACKET IN TIMEOUT OF 100ms*/
	Timer1 = 100;
	do{
		token = rcvr_spi();
	}while((token == 0xFF) && Timer1);
	/*IF NOT VALID DATA TOKEN, RETURN WITH ERROR*/
	if(token != 0xFE) return FALSE;

	do{
		/*RECEIVE THE DATA BLOCK INTO BUFFER*/
		rcvr_spi_m(buff++);
		rcvr_spi_m(buff++);
	}while(btr -= 2);
		/*DISCARD CRC*/
		rcvr_spi();
		rcvr_spi();
		/*RETURN WITH SUCESS*/
		return TRUE;
}

/*************************************************************
 * 				 SEND A DATA PACKET TO MMC	 				*
 *************************************************************/

#if	_READONLY == 0

/*512 BYTE DATA BLOCK TO BE TRANSMITTED
 *DATA/STOP TOKEN*/

static BOOL xmit_datablock(const BYTE *buff, BYTE token){
	BYTE resp, wc;

		if(wait_ready()!=0xFF) return FALSE;
		/*XMIT DATA TOKEN*/
		xmit_spi(token);
		if(token!= 0xFD){
			wc = 0;
			do{
			/*XMIT THE 512 BYTE DATA BLOCK TO MMC*/
			xmit_spi(*buff++);
			xmit_spi(*buff++);
			}while(--wc);
			xmit_spi(0xFF);
			xmit_spi(0xFF);
			resp = rcvr_spi();
			if((resp & 0x1F) != 0x05)
				return FALSE;
		}
	return TRUE;
}
#endif	/*READ ONLY*/

/*************************************************************
 * 				 SEND A DATA PACKET TO MMC	 				*
 *************************************************************/

/*COMMAND BYTE*/
/*ARGUMENT*/
static BYTE send_cmd(BYTE cmd, DWORD arg){

	BYTE n, res;

	if(wait_ready()!=0xFF) return 0xFF;
		/*SEND COMMAND PACKET*/

		xmit_spi(cmd);					/*COMMAND*/
		xmit_spi((BYTE)(arg >> 24));		/*Argument[31..24]*/
		xmit_spi((BYTE)(arg >> 16));		/*Argument[23..16]*/
		xmit_spi((BYTE)(arg >> 8));		/*Argument[15..8]*/
		xmit_spi((BYTE)arg);				/*Argument[7..0]*/

		n = 0xFF;						/*DUMMY CRC + STOP*/

		if(cmd == CMD0) n = 0x95;		/*VALID CRC FOR CMD0(0)*/
		if(cmd == CMD8) n = 0x87;		/*VALID CRC FOR CMD8(0x1AA)*/

		xmit_spi(n);

		/*RECEIVE COMMAND RESPONSE*/
		if(cmd == CMD12) rcvr_spi();

		n = 10;							/*WAIT A VALID RESPONSE IN TIMEOUT OF 10 ATTEMPS*/

		do
			res = rcvr_spi();
		while ((res & 0x80) && --n);

		return res; /*RETURN WITH THE RESPONSE VALUE*/

}
/*************************************************************
 *SEND THE SPECIAL COMMAND USED TO TERMINAT A MULTI-SECTOR
 *
 *THIS IS THE ONLY COMMAND WHICH CAN BE SENT WHILE THE SDCARD
 *IS SENDING DATA. THE SDCARD SPEC INDICATES THAT THE DATA
 *TRANSFER WILL STOP 2 BYTES AFTER THE 6 BYTE CMD12 COMMAND
 *IS
 *************************************************************/


static BYTE send_cmd12(void){
 BYTE n, res, val;
/*FOR CMD12, WE DON'T WAIT FOR THE CARD TO BE IDLE BEFORE WE SEND
 *NEW COMMAND*/
 xmit_spi(CMD12);
 xmit_spi(0);
 xmit_spi(0);
 xmit_spi(0);
 xmit_spi(0);
 xmit_spi(0);

 /*READ UP TO 10 BYTES FROM THE CARD, REMEMBERING THE VALUE READ
  *IF IT'S NOT 0XFF */

 	 for(n = 0; n <10; n++){
 		 val = rcvr_spi();
 		 if (val != 0xFF){

 			 res = val;

 		 }
 	 }
 	 /*RETURN WITH RESPONSE VALUES*/
 	 return res;

}

/*************************************************************
* 						PUBLIC FUNCTIONS		 				*
*/


/*************************************************************
 * 					INITIALIZE DISK 	DRIVE	 				*
 *************************************************************/

DSTATUS disk_initialize(BYTE drv){
	/*PHISICAL DRIVE NUMBER (0)*/
	BYTE n, ty, ocr[4];

	if(drv) return STA_NOINIT;				/*SUPPORTS ONLY SINGLE DRIVE*/
	if(Stat & STA_NODISK) return Stat;		/*NO CARD IN THE SOCKET*/

	power_on();								/*FORCE SOCKET POWER ON*/
	send_initial_clock_train();				/*ENSURE THE CARD IS  IN SPI MODE*/

	SELECT();																	/*CS = L*/
	ty = 0;

	if(send_cmd(CMD0, 0) == 1){				/**/
		Timer1 = 100;															/*INITIALIZATION TIMEOUT OF 1000msec*/
		if(send_cmd(CMD8, 0x1AA) == 1){											/*SDC Ver2+*/
			for(n = 0;n < 4; n++) ocr[n] = rcvr_spi();
			if(ocr[2] == 0x01 && ocr[3] == 0xAA){
				do{
					if(send_cmd(CMD55,0) <= 1 && send_cmd(CMD41, 1UL << 30) == 0) break;
				}while(Timer1);
				if(Timer1 && send_cmd(CMD58, 0) == 0){ 							/*CHECK CSS BIT*/
					for(n = 0;n < 4; n++) ocr[n] = rcvr_spi();
					ty = (ocr[0] & 0x40) ? 6 : 2;
				}
			}
		}else{																	/*SDC Ver1 OR MMC*/
			ty = (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) <= 1 ) ? 2 : 1; 	/*SDC:MMC*/
			do{
				if(ty == 2){
					if(send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) == 0) break;
				}else{
					if(send_cmd(CMD1, 0) == 0) break;							/*CMD1*/
				}
			}while(Timer1);
			if(!Timer1 || send_cmd(CMD16, 512) != 0) 							/*SELECT R/W BLOCK LENGTH*/
				ty = 0;
		}
	}
	CardType = ty;
	DESELECT();																	/*CS = H*/
	rcvr_spi();																	/*IDLE (RELEASE DO)*/

	if(ty){																		/*INITIALIZATION SUCESSED*/
		Stat &= ~STA_NOINIT;														/*CLEAR STA_NOINIT*/
		set_max_speed();															/**/
	}else{																		/*INITIALIZATION FAILED*/
		power_off();
	}
	return  Stat;
}


/*************************************************************
 * 						GET DISK STATUS		 				*
 *************************************************************/

DSTATUS disk_status(BYTE drv){													/*PHISICAL DRIVE (0)*/
	if(drv) return STA_NOINIT;													/*SUPPORT ONLY SINGLE DRIVE*/
	return Stat;
}



/*************************************************************
 * 						 READ SECTOR			 				*
 *************************************************************/

/*1-PHISICAL DRIVE NUMBER (0)*/
/*2-POINTER TO THE  DATA BUFFER TO STORE READ DATA*/
/*3-START SECTOR NUMBER (LBA)*/
/*4-SECTOR COUNT (1... 255)*/

DRESULT disk_read(BYTE drv, BYTE *buff, DWORD sector, BYTE count){

	if(drv || !count)return RES_PARERR;
	if(Stat & STA_NOINIT) return RES_NOTRDY;

	if(!(CardType & 4)) sector *= 512;											/*CONVERT TO BYTE ADDRESS IF NEED*/

	SELECT();																	/*CS = L*/
	if(count == 1){																/*SINGLE BLOCK READ*/
		if((send_cmd(CMD17, sector) == 0)										/*READ SINGLE BLOCK*/
			&& rcvr_datablock(buff, 512))
			count = 0;
	}else{																		/*MULTIPLE BLOCK READ*/
		if(send_cmd(CMD18, sector) == 0){
			do{
				if(!rcvr_datablock(buff, 512))break;
				buff += 512;
			}while(--count);
			send_cmd12();															/*STOP TRANSMISSION*/
		}
	}


	DESELECT();																	/*CS = H*/
	rcvr_spi();																	/*IDLE (RELEASE DO)*/

	return count ? RES_ERROR : RES_OK;
}

/*************************************************************
 * 						WRITE SECTOR 		 				*
 *************************************************************/
#if _READONLY == 0
	/**/
	/**/
	/**/
	/**/

	DRESULT disk_write(BYTE drv, const  BYTE *buff, DWORD sector, BYTE count){

		if(drv || !count)return RES_PARERR;
		if(Stat & STA_NOINIT) return RES_NOTRDY;
		if(Stat & STA_PROTECT) return RES_WRPRT;

		if (!(CardType & 4)) sector *= 512;									/*CONVERT TO BYTE ADDRESS IF NEEDED*/

		SELECT();															/*CS = L*/

		if(count == 1){														/*SINGLE BLOCK WRITE*/
			if((send_cmd(CMD24, sector) == 0)									/*WRITE BLOCK*/
			&& xmit_datablock(buff, 0xFE))
			count = 0;
		}else{																/*MULTIPLE BLOCK WRITE*/
			if(CardType & 2){
				send_cmd(CMD55, 0); send_cmd(CMD23, count);					/*ACMD23*/
			}
			if(send_cmd(CMD25, sector) == 0){
				do{
					if(!xmit_datablock(buff, 0xFC)) break;
					buff +=512;

				}while(--count);
				if(!xmit_datablock(0, 0xFD))									/*STOP_TRAN TOKEN*/

					count = 1;
			}

		}

		DESELECT();															/*CS = H*/
		rcvr_spi();															/*IDLE (RELEADE DO)*/

		return count ? RES_ERROR : RES_OK;

	}
#endif/*READ ONLY*/

/*************************************************************
* 					MISCELANEOUS FUNCTIONS 		 			*
*************************************************************/

	/*FISICAL DRIVE NUMBER (0)*/
	/*CONTROL CODE*/
	/*BUFFER SEND/RECEIVE CONTROL DATA*/
	DRESULT disk_ioctl(BYTE drv, BYTE ctrl, void *buff){

		DRESULT res;
		BYTE n, csd[16], *ptr = buff;
		WORD csize;

		if(ctrl == CTRL_POWER){
			switch(*ptr){
				case 0:														/*SUB CONTROL CODE == 0 (POWER OFF)*/
					if(chk_power())
						power_off();											/*POWER OFF*/
				break;
				case 1:														/*SUB CONTROL CODE == 1 (POWER ON)*/
					power_on();
					res = RES_OK;
				break;
				case 2:														/*SUB CONTROL CODE == 2 (POWER_GET)*/
					*(ptr+1) = (BYTE)chk_power();
					res = RES_OK;
				break;
				default:
					res =RES_PARERR;
			}

		}else{
			if(Stat & STA_NOINIT) return RES_NOTRDY;

			SELECT();														/*CS = L*/


			switch(ctrl){

				case GET_SECTOR_COUNT:												/*GET THE NUMBER SECTOR'S ON THE DISK)*/
					if((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)){
						if((	csd[0] >> 6) == 1){										/*SDC Ver 2.00*/
							csize = csd[9] + ((WORD)csd[8] << 8) + 1;
							*(DWORD*)buff = (DWORD)csize << 10;

						}else{														/*MMC SDC Ver 1.XX*/
							n =	(csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
							csize =	(csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[7] & 3) << 10) + 1;
							*(DWORD*)buff = (DWORD)csize << (n-9);
						}
						res = RES_OK;
					}
				break;

				case GET_SECTOR_SIZE:												/*SUB CONTROL CODE == 1 (POWER ON)*/
					*(DWORD*)buff = 512;
					res = RES_OK;
				break;

				case CTRL_SYNC:														/*SUB CONTROL CODE == 2 (POWER_GET)*/
					if(wait_ready() == 0xFF)
					res = RES_OK;
				break;

				case MMC_GET_CSD:													/*SUB CONTROL CODE == 2 (POWER_GET)*/
					if (send_cmd(CMD9, 0) == 0        								/* READ_CSD */
				    && rcvr_datablock(ptr, 16))
				    res = RES_OK;
				break;

				case MMC_GET_CID:													/*SUB CONTROL CODE == 2 (POWER_GET)*/
					if (send_cmd(CMD10, 0) == 0      								/* READ_CID */
		            	&& rcvr_datablock(ptr, 16))
			        res = RES_OK;
				break;

				case MMC_GET_OCR:													/*SUB CONTROL CODE == 2 (POWER_GET)*/
					if (send_cmd(CMD58, 0) == 0) {    								/* READ_OCR */
						for (n = 0; n < 4; n++)
						*ptr++ = rcvr_spi();
						res = RES_OK;
					}


				 default:
					res =RES_PARERR;
			}

			DESELECT();																/*CS = H*/
			rcvr_spi();																/*IDLE (RELEASE DO)*/

		}
		return res;
	}

/*************************************************************
*  					MISCELANEOUS FUNCTIONS 		 			*
**************************************************************/

void disk_timerproc(void){
	BYTE n;
n = Timer1;
 if (n) Timer1 =	--n;																	/*100Hz DECREMENT TIMER*/
 n = Timer2;
 if(n) Timer2 = --n;

}

/*************************************************************
*  				USER PROVIDER TIMER FUNCTION 				*
**************************************************************/
DWORD get_fattime (void)	{
return ((2007UL-1980) << 25) | (6UL << 21) | (5UL << 16)
		| (11U << 11) | (38U << 5) | (0U >> 1);
}








5518.diskio.h

8233.integer.h

/*****************************************************************/
/*********                                               *********/
/********* AUTOR:    ANTONIO ARMANDO BIZA FERREIRA       *********/
/********* PROJECTO: ECG                                 *********/
/********* DATA:     01-02-2017                          *********/
/********* IDE:      CODE COMPOSER STUDIO V5             *********/
/********* MCU:      MSP432                              *********/
/*********                                               *********/
/********* FILE:     LCD.C                               *********/
/*********                                               *********/
/*****************************************************************/


/*****************************************************************/
/********* INCLUDE                                       *********/
/*****************************************************************/
#include "lcd.h"

/*****************************************************************/
/********* DEFINES                                       *********/
/*****************************************************************/

#define EN                      (PORT2 + BIT3)
#define RS                      (PORT6 + BIT7)

#define D4                      (PORT2 + BIT6)
#define D5                      (PORT2 + BIT4)
#define D6                      (PORT5 + BIT6)
#define D7                      (PORT6 + BIT6)

/*COMMAND*/
#define CLEAR                   0x01

/*****************************************************************/
/********* LOCAL FUNCTIONS                               *********/
/*****************************************************************/

/*LCD PIN OUT DIRECTION*/
void lcdDirPinOut(unsigned int pin){

    if((pin & 0xFF00) == PORT2){

        P2->DIR |= (pin & 0x00FF);

    }else if((pin & 0xFF00) == PORT5){

        P5->DIR |= (pin & 0x00FF);

    }else{

        P6->DIR |= (pin & 0x00FF);

    }

}

/*LCD PIN OUT SET*/
void lcdSetPinOut(unsigned int pin){

    if((pin & 0xFF00) == PORT2){

        P2->OUT |= (pin & 0x00FF);

    }else if((pin & 0xFF00) == PORT5){

        P5->OUT |= (pin & 0x00FF);

    }else{

        P6->OUT |= (pin & 0x00FF);

    }

}


/*LCD PIN OUT CLR*/
void lcdClrPinOut(unsigned int pin){

    if((pin & 0xFF00) == PORT2){

        P2->OUT &= ~(pin & 0x00FF);

    }else if((pin & 0xFF00) == PORT5){

        P5->OUT &= ~(pin & 0x00FF);

    }else{

        P6->OUT &= ~(pin & 0x00FF);

    }

}

void lcdSetValue(unsigned char value){

     if(value & 0x08){
            lcdSetPinOut(D7);
        }else{
            lcdClrPinOut(D7);
        }

        if(value & 0x04){
            lcdSetPinOut(D6);
        }else{
            lcdClrPinOut(D6);
        }

        if(value & 0x02){
            lcdSetPinOut(D5);
        }else{
            lcdClrPinOut(D5);
        }

        if(value & 0x01){
            lcdSetPinOut(D4);
        }else{
            lcdClrPinOut(D4);
        }
        delay_us(5);
}

void lcdTriggerEN(){

    lcdSetPinOut(EN);
    delay_us(5);
    lcdClrPinOut(EN);
    delay_us(5);
}

void lcdWriteData(unsigned char data){
    lcdSetPinOut(RS);           // Set RS to Data
    lcdSetValue(data >> 4);     // Upper nibble
    lcdTriggerEN();
    lcdSetValue(data);          // Lower nibble
    lcdTriggerEN();
    delay_us(30);               // Delay > 50 us
}

void lcdWriteCmd(unsigned char cmd){
    lcdClrPinOut(RS);           // Set RS to Cmd
    lcdSetValue(cmd >> 4);      // Upper nibble
    lcdTriggerEN();
    lcdSetValue(cmd);           // Lower nibble
    lcdTriggerEN();
    delay_ms(2);                // Delay > 5ms
}




/*****************************************************************/
/********* GLOBAL FUNCTIONS                              *********/
/*****************************************************************/

/*
 *
 */
void LCD_PortConfig(void){
    // Direction
    lcdDirPinOut(D4);
    lcdDirPinOut(D5);
    lcdDirPinOut(D6);
    lcdDirPinOut(D7);
    lcdDirPinOut(EN);
    lcdDirPinOut(RS);
}


/*
 *
 */
void LCD_Initialize(void){

    delay_us(80);
    lcdWriteCmd(0x28); // 4-bit, 2 line, 5x8
    P2->OUT = 0x03;      // Start LCD (send 0x03)
    lcdTriggerEN();    // Send 0x03 3 times at 5ms then 100 us
    delay_ms(2);
    lcdTriggerEN();
    delay_ms(2);
    lcdTriggerEN();
    delay_ms(2);

    lcdWriteCmd(0x28); // 4-bit, 2 line, 5x8
    P2->OUT = 0x02;      // Switch to 4-bit mode
    lcdTriggerEN();
    delay_ms(2);


    lcdWriteCmd(0x28); // 4-bit, 2 line, 5x8
    lcdWriteCmd(0x08); // Instruction Flow
    lcdWriteCmd(0x01); // Clear LCD
    lcdWriteCmd(0x06); // Auto-Increment
    lcdWriteCmd(0x0C); // Display On, No blink
}


void LCD_SetText(char* text, int x, int y){
    unsigned int i;

    if (x < 16) {
        x |= 0x80;      // Set LCD for first line write
        switch (y){
        case 1:
            x |= 0x40;  // Set LCD for second line write
            break;
        case 2:
            x |= 0x60;  // Set LCD for first line write reverse
            break;
        case 3:
            x |= 0x20;  // Set LCD for second line write reverse
            break;
        }
        lcdWriteCmd(x);
    }

    i = 0;
    while (text[i] != '\0') {
        lcdWriteData(text[i]);
        i++;
    }
}

void LCD_SetInt(int val, int x, int y){
    char number_string[16];

    sprintf(number_string, "%d", val); // Convert the integer to character string
    LCD_SetText(number_string, x, y);
}

void LCD_Clear(){
    lcdWriteCmd(CLEAR);
}

void LCD_LoadSymbols(void){
    int j;

    static char empty[]   = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    static char heart[]   = {0x00, 0x0A, 0x1F, 0x1F, 0x1F, 0x0E, 0x04, 0x00};
    static char bat_100[] = {0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
    static char bat_75[]  = {0x0E, 0x1F, 0x11, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
    static char bat_50[]  = {0x0E, 0x1F, 0x11, 0x11, 0x11, 0x1F, 0x1F, 0x1F};
    static char bat_25[]  = {0x0E, 0x1F, 0x11, 0x11, 0x11, 0x11, 0x1F, 0x1F};
    static char bat_0[]   = {0x0E, 0x1F, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1F};

    lcdWriteCmd(0x40);

    for(j=0;j!=8;j++){
        lcdWriteData(empty[j]);
    }

    for(j=0;j!=8;j++){
        lcdWriteData(heart[j]);
    }

    for(j=0;j!=8;j++){
        lcdWriteData(bat_100[j]);
    }

    for(j=0;j!=8;j++){
        lcdWriteData(bat_75[j]);
    }
    for(j=0;j!=8;j++){
        lcdWriteData(bat_50[j]);
    }
    for(j=0;j!=8;j++){
        lcdWriteData(bat_25[j]);
    }
    for(j=0;j!=8;j++){
        lcdWriteData(bat_0[j]);
    }
    lcdWriteCmd(CMD_END);
}

void LCD_SetSymbol(unsigned char symbol, unsigned char offset, unsigned char line){
    lcdWriteCmd(line+offset);
    lcdWriteData(symbol);
}

1300.lcd.h

/*****************************************************************/
/*********                                               *********/
/********* AUTOR:    ANTONIO ARMANDO BIZA FERREIRA       *********/
/********* PROJECTO:                                     *********/
/********* DATA:     01-04-2017                          *********/
/********* IDE:      CODE COMPOSER STUDIO V7             *********/
/********* MCU:      msp432                              *********/
/*********                                               *********/
/********* FILE:     MAIN.C                              *********/
/*********                                               *********/
/*****************************************************************/
 
/*****************************************************************/
/********* INCLUDE                                       *********/
/*****************************************************************/
#include <msp.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "main.h"                /*MACROS E DEFINE O SOFTWARE*/
#include "lcd.h"
#include "diskio.h"
#include "integer.h"
#include "pff.h"
#include "spi.h"

/*DEFINE THE SIZE OF THE BUFFER  THAT HOLD  THE PATH*/
unsigned int offSetBuffer = 0;
volatile unsigned int BUFFER[1024];
/*DEFINE THE WORK DIRECTORY BUFFER*/

/*****************************************************************/
/********* 					STRUCTURES                  *********/
/*****************************************************************/
unsigned char tmp = 0;

volatile FRESULT res_mount, res_open, res_seek, res_write;
/*FILE OBJECT*/
static FIL fsrc, fdst;						/*FILE SOURCE|FILE DESTINATION*/





/*****************************************************************/
/********* CUSTOM CHARACTERS                             *********/
/*****************************************************************/



/*****************************************************************/
/********* MAIN                                          *********/
/*****************************************************************/


int main(void){
/*
 * MAIN
 */
	/*HALTING WDT AND DISABLING MASTER INTERRUPTS*/
	WatchDogHold();
	/*CONFIGURE THE LCD PORT*/
    LCD_PortConfig();
    /*INITIALIZE THE LCS*/
    LCD_Initialize();
    /*CLEAR ALL LCD CHARACTERS*/
    LCD_Clear();
    /*WELCOMME START MESSAGE*/
    Welcomme();
    /*INITIALIZE SDcard*/
    SDCARD_Initialize();

    while(1){

    }
    
}



/*****************************************************************/
/********* GLOBAL FUNCTIONS                              *********/
/*****************************************************************/

void WatchDogHold(void)
{
   WDTCTL = WDTPW + WDTHOLD;
}

/*INITIALIZE SDcard*/
void SDCARD_Initialize(){
	 /*FATS OBJECT*/
	 FATFS FatFs;
	 //WORD bw;
	 UINT fa;

    /*CONFIGUURE SPI LIKE MASTER */
    spiMasterConfig();
    /*OPEN SPI COMUNICATION*/
    spi_Open();


    /*MOUNTING THE FILE SYSTEM, USING LOCAL DISK*/
    	res_mount = f_mount(0, NULL);

    	/*VERIFY IF DISK IS MONTED */
    	if(res_mount != FR_OK){
    		LCD_SetText("NO_SDCARD",4,0);

    	}else{
    		LCD_SetText("SDCARD_OK", 4, 0);
    		/*CREATE A FILE INSIDE SDCARD TO WRITE INSIDE*/
    		res_open = f_open(&fdst, "test.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
    		if(res_open == FR_OK){
    			LCD_SetText("FILE_CREATED", 4, 1);
    			res_seek = f_lseek(&fdst, f_size(&fdst));
    			if(res_seek == FR_OK)
    			res_write = f_write(&fdst, "Alpha Beta\n", 11, &fa);
    			//f_printf(&fsrc, "%6d,%3d%%", -200, 5)--------------
    			//f_printf(&fsrc, "%6d,%3d%%", -200, 5);

    			/*bw = 0;
    			Line[0] = 66;
    			Line[1] = 65;
    			Line[3] = '\0';*/
    			//res = f_write(&fil, BUFFER, 1024, &bw);
    		   // f_printf(&fil, "%02u/%02u/%u, %2u:%02u\n", Mday, Mon, Year, Hour, Min);

  //  			f_write(0,0,&bw);
    		}
    	}

}

void SDCARD_Close(){
	f_close(&fdst);
	f_close(&fsrc);
}

void Welcomme(void){
	 LCD_SetText("welcome",4,0);
}

/*****************************************************************/
/********* END                                           *********/
/*****************************************************************/


8741.main.h

2465.pff.c

4532.pff.h

#include "msp.h"
#include <stdint.h>
#include "spi.h"



#define ASSERT_CS()			(P4->OUT &= ~BIT6)
#define DEASSERT_CS()		(P4->OUT |= BIT6)

/*SPI MASTER CONFIGURATION PARAMETER*/
									/*SET SPI MASTER | MSB FIRST | PHASE  |  HIGHT POLARITY |*/
#define SPI_MODE_0 					EUSCI_B_CTLW0_MST | EUSCI_B_CTLW0_MSB | EUSCI_B_CTLW0_CKPH | EUSCI_B_CTLW0_CKPL /*CPOL = 1 CPHA = 1 */
									/*SET SPI MASTER | MSB FIRST | PHASE  |  LOW POLARITY |*/
#define SPI_MODE_3 					EUSCI_B_CTLW0_MST | EUSCI_B_CTLW0_MSB | EUSCI_B_CTLW0_CKPH | 0X00 /* CPOL = 0 CPHA = 0 */


/*
 * spi_initialize() - Initialize and enable the SPI module
 * P4.6 - CS (active low)
 * P1.6 - MOSI UCB0SIMO
 * P1.5 - CLK UCB0CLK
 * P1.7 - MISO UCB0SOMI
 */


 void spiMasterConfig(void){

	 EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_SWRST;							/*PUT EUSCI_B_CTLW0_SWRST STATE MACHINE IN RESET*/
	 EUSCI_B0->CTLW0  = EUSCI_B_CTLW0_SWRST | SPI_MODE_0;				/*REMAIN UCB0CTW0 STATE MACHINE IN RESET | SPI_MODE_0*/
	 EUSCI_B0->CTLW0 |= EUSCI_A_CTLW0_SSEL__SMCLK;					/*SMCLK CLOCK SOURCE SELECT*/
	 EUSCI_B0->BRW = LOBYTE(SPI_400KHz);			// 300KHz
	 EUSCI_B1->BRW = HIBYTE(SPI_400KHz);
	 EUSCI_B0->CTLW1 &= ~EUSCI_A_CTLW0_SWRST;						/*RELEASE FOR THE OPERATION*/
};

 int spi_Close(Fd_t fd){
     return 0;														/*NONOS_RET_OK*/
 }

Fd_t spi_Open(void){

	 /*SELECT P1.5 P1.6 AND P1.7 IN SPI_MODE*/
	 P1->SEL0 |= BIT5 | BIT6 | BIT7;									/*SET PINS P1.5, P1.6, P1.7 AS SPI PIN FUNCIONALITY*/
	 /*CS SETUP*/
	 P4->SEL0 |= BIT6;												/*USCI*/
	 P4->OUT |= BIT6;												/*CS ON P4.6 START OUT DISABLE*/
	 P4->DIR |= BIT6;												/*CS CONFIGURED AS OUTPUT*/

	/*CONFIGURING SPI IN 3WIRE MASTER MODE*/
	// SPI_initMaster(EUSCI_B0_BASE, &spiMasterConfig());
	 /*ENABLE SPI MODULE*/
	// SPI_enableModule(EUSCI_B0_BASE);

	 return 0;														/*NONOS_RET_OK;*/
 }



int spi_Write(Fd_t fd, unsigned char *pBuff, int len)
{
    int len_to_return = len;

    ASSERT_CS();
    while (len)
    {
        while (!(EUSCI_B0->IFG&EUSCI_B_IFG_TXIFG));
        EUSCI_B0->TXBUF = *pBuff;
        while (!(EUSCI_B0->IFG&EUSCI_B_IFG_TXIFG));
        EUSCI_B0->TXBUF;
        len --;
        pBuff++;
    }

    DEASSERT_CS();

    return len_to_return;
}




int spi_Read(Fd_t fd, unsigned char *pBuff, int len)
{
    int i = 0;

    ASSERT_CS();

    for (i = 0; i < len; i ++)
    {
        while (!(EUSCI_B0->IFG&EUSCI_B_IFG_TXIFG));
        UCB0TXBUF = 0xFF;
        while (!(EUSCI_B0->IFG&EUSCI_B_IFG_TXIFG));
        pBuff[i] = UCB0RXBUF;
    }

    DEASSERT_CS();

    return len;
}

uint8_t SPI_receiveData(uint32_t modeInstance){
	uint8_t valuespirx;

	  ASSERT_CS();


	        while (!(EUSCI_B0->IFG&EUSCI_B_IFG_TXIFG));
	        EUSCI_B0->TXBUF = 0xFF;
	        while (!(EUSCI_B0->IFG&EUSCI_B_IFG_TXIFG));
	        valuespirx=  EUSCI_B0->RXBUF;


	    DEASSERT_CS();

	    return valuespirx;

}
void SPI_transmitData(uint32_t modeInstance, uint_fast8_t transmitData){
	 ASSERT_CS();

	        while (!(EUSCI_B0->IFG&EUSCI_B_IFG_TXIFG));
	        EUSCI_B0->TXBUF = transmitData;
	        while (!(EUSCI_B0->IFG&EUSCI_B_IFG_TXIFG));
	        EUSCI_B0->TXBUF;

	    DEASSERT_CS();
}


7245.spi.h

  • armandoffer,

    I can try and help you with this, but I do not have the specific hardware you are talking about so i'll do my best to provide assistance from afar. With regards to your request for help. I need more details, what exactly do you need help with?

    With regards to hardware, I would also make sure you are using a Red LaunchPad. The Red MSP432 LaunchPads are Rev2.0 and contain Rev C silicon. The black LaunchPad's have XMS Rev B silicon which is no longer recommended to be used as it was pre-RTM material.

    To maybe help, there are two directions you can go in my eyes. You can continue to use this older project that was written before we updated everything to CMSIS, and now convert your code to CMSIS. If you chose this, you can use Section 3 (Specifically 3.1.1 and beyond) to help guide you through the process of updating your code to CMSIS standard.

    www.ti.com/.../slaa700a.pdf

    If using a Red Launchpad, Another place you could start is by using the SimpleLink MSP432 SDK TI Driver for doing SD card reading. There is a simple example down below. For more information on the SimpleLink SDK, go to www.ti.com/simplelink

    dev.ti.com/.../

    The above example enables you to read and write data onto an SD Card (SPI interface).
  • Also, here is a basic example on how to change the register names from MSP classic to CMSIS compliant.

    P2OUT = 0x02; // MSP Classic
    P2->OUT = 0x02; // CMSIS 

    The above link is also a good resource.

  • HelloEvan, i give you more information
    I am using the MSP432 black, the problem is that I no longer have much time to submit this work, and the purchase and shipping of the MSP432 red will limit me time.Yes I will update the entire code for CMSIS If you can help me, I am quite newbie in the micro controller world. I would like to continue using standard CMSIS without driverlib
  • Armandoferr,

    All of the examples that are register level for MSP432 are located in this folder and are all CMSIS compliant. This should be a great starting point for you as you port your code to be CMSIS compliant.

    dev.ti.com/.../

    If you have specific questions, feel free to ask!
  • Evan Wakefield,

    I want to change the syntax for CMSIS, and I have been able to get results with the SDcard, however I have some difficulties when I initialize the SDcard I can not create a file inside the SDcard, I tried everything, can you help me?

    My code:

    /*DEFINE THE SIZE OF THE BUFFER  THAT HOLD  THE PATH*/
    unsigned int offSetBuffer = 0;
    volatile unsigned int BUFFER[1024];
    /*DEFINE THE WORK DIRECTORY BUFFER*/
    
    /*****************************************************************/
    /********* 					STRUCTURES                  *********/
    /*****************************************************************/
    unsigned char tmp = 0;
    
    volatile FRESULT res;
    static FIL fsrc, fdst;						/*FILE SOURCE|FILE DESTINATION*/
    
    
    
    
    
    /*****************************************************************/
    /********* CUSTOM CHARACTERS                             *********/
    /*****************************************************************/
    
    
    
    /*****************************************************************/
    /********* MAIN                                          *********/
    /*****************************************************************/
    
    
    
    /*
     * MAIN
     */
    int main(void){
    	/*HALTING WDT AND DISABLING MASTER INTERRUPTS*/
    	WatchDogHold();
    	/*CONFIGURE THE LCD PORT*/
        LCD_PortConfig();
        /*INITIALIZE THE LCS*/
        LCD_Initialize();
        /*CLEAR ALL LCD CHARACTERS*/
        LCD_Clear();
        /*WELCOMME START MESSAGE*/
        Welcomme();
        /*INITIALIZE SDcard*/
        SDCARD_Initialize();
    
        while(1){
    
        }
        
    }
    
    
    
    /*****************************************************************/
    /********* GLOBAL FUNCTIONS                              *********/
    /*****************************************************************/
    
    void WatchDogHold(void)
    {
       WDTCTL = WDTPW + WDTHOLD;
    }
    
    /*INITIALIZE SDcard*/
    void SDCARD_Initialize(){
    	FATFS g_sFatFs;
    	WORD bw;
    
        /*CONFIGUURE SPI LIKE MASTER */
        spiMasterConfig();
        /*OPEN SPI COMUNICATION*/
        spi_Open();
        /*MOUNTING THE FILE SYSTEM, USING LOCAL DISK*/
        	res = f_mount(0,&g_sFatFs);
        	/*VERIFY IF DISK IS MONTED */
        	if(res != FR_OK){
        		LCD_SetText("NO SDCARD",4,0);
        	}else{
        		LCD_SetText("SDCARD OK",4,0);
        		/*CREATE A FILE INSIDE SDCARD TO WRITE INSIDE*/
        		res = f_open(&fdst, "teste.txt", FA_CREATE_NEW| FA_READ);
    
        		if(res == FR_OK){
        			LCD_SetText("FILE CREATED",4,1);
        			res = f_open(&fsrc, "teste.txt", FA_OPEN_EXISTING | FA_WRITE);
    
        			res = f_write(&fsrc, BUFFER, 1024, &bw);
        			//f_printf(&fsrc, "%6d,%3d%%", -200, 5)--------------
        			//f_printf(&fsrc, "%6d,%3d%%", -200, 5);
    
        			/*bw = 0;
        			Line[0] = 66;
        			Line[1] = 65;
        			Line[3] = '\0';*/
        			//res = f_write(&fil, BUFFER, 1024, &bw);
    
      //  			f_write(0,0,&bw);
        		}
        	}
    
    }
    
    void SDCARD_Close(){
    	f_close(&fdst);
    	f_close(&fsrc);
    }
    
    void Welcomme(void){
    	 LCD_SetText("welcome",4,0);
    }

    What am I doing wrong?

  • Armandoferr,

    Without the specific hardware you are using, I'm limited to being able to test what you've sent, but I can offer suggestions. Can you give me some details into what exactly you have done already when you say you've tried everything? That will help me get a better starting point to be able to suggest what might be wrong. Can you describe the error you are getting? Have you used a logic analyzer to ensure that the SPI is working as intended?
  • Armandoferr,

    We do have an SD card example using TI-Drivers that you could try as well and see if it works.
    dev.ti.com/.../
    In that example, you can read and write data onto an SD Card (SPI interface). I would make sure that the SPI lines you use in your project, are the same SPI pins used in this example, if not, you can easily modify the code to adjust for the SPI pins you are using.

    Use the readme to walk through how to utilize the example.
  • I am facing some problems with my project I need make a data logger to register some especial acquisition data. Well I have done with auxily of SDcard Boosterpack published by bluehash, my SDcard data logger. But something goes wrong, if the Sdcard slot doesn't have card he shows me SDCARD_OK, and when I put the card shows me the same, what I am doing wrong . What can I do to change this problem. I change update the original files to my new version with CMSIS standard.
  • armandoferr,

    With regards to being able to debug your code, I'm not going to be able to help you on this because I do not have your hardware. My guess is that your f_mount function is returning the wrong value maybe. I would start by using a logic analyzer to see if you can find any anomaly when communicating with the SD card over SPI and go from there.

    Again, as an aside, I would suggest that you look at the SD card example we provide that uses TI RTOS. dev.ti.com/.../

    This example we built ourselves, and know it works. I would investigate how you can modify this example to work with your SD card.

    In order to run the example above, you will need to have the Red LaunchPad due to software changes that occurred from the XMS silicon on the black launchpad and the silicon on the red launchpad.
  • This issue has been solved. I made a code with recourse to CMSIS, and i got the SDcard to work, using part of the FATFS library. tanks

**Attention** This is a public forum