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:
#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);
}
/*****************************************************************/
/********* *********/
/********* 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);
}
/*****************************************************************/
/********* *********/
/********* 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 *********/
/*****************************************************************/
#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();
}

