#include "lpspi_master_driver.h" #include "Cpu.h" #include "clockMan1.h" #include "lpspiCom1.h" #include "lpspi_shared_function.h" #include "stdio.h" #include "string.h" #include "ff.h" #define LPSPI_MASTER_INSTANCE 0 #define SD_CS_PORT PTB #define SD_CS_PIN 5 lpspi_master_config_t spiConfig; lpspi_state_t lpspiState; int exit_code = 0; void SPI_init() { // Initialize clock CLOCK_DRV_Init(&clockMan1_InitConfig0); // Initialize pins PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr); // Initialize LPSPI Master LPSPI_DRV_MasterGetDefaultConfig(&spiConfig); // Initialize the LPSPI master module LPSPI_DRV_MasterInit(LPSPI_MASTER_INSTANCE, &lpspiState, &spiConfig); /* Set CS pin as output */ PINS_DRV_SetPinsDirection(SD_CS_PORT, 1 << SD_CS_PIN); /* Set CS pin high (inactive) */ PINS_DRV_SetPins(SD_CS_PORT, 1 << SD_CS_PIN); } void CS_ENABLE() { /* Set CS pin low (active) */ PINS_DRV_ClearPins(SD_CS_PORT, 1 << SD_CS_PIN); } void CS_DISABLE() { /* Set CS pin high (inactive) */ PINS_DRV_SetPins(SD_CS_PORT, 1 << SD_CS_PIN); } uint8_t SPI_transfer(uint8_t data) { uint8_t receiveData; /* Enable CS before starting transfer */ CS_ENABLE(); /* Perform SPI transfer */ LPSPI_DRV_MasterTransferBlocking(LPSPI_MASTER_INSTANCE, &data, &receiveData, 1, 100); /* Disable CS after transfer */ CS_DISABLE(); return receiveData; } void SD_powerUpSeq() { // Make sure card is deselected CS_DISABLE(); // Give SD card time to power up OSIF_TimeDelay(1); // Send 80 clock cycles to synchronize for (uint8_t i = 0; i < 10; i++) SPI_transfer(0xFF); // Deselect SD card CS_DISABLE(); //SPI_transfer(0xFF); } void SD_command(uint8_t cmd, uint32_t arg, uint8_t crc) { // Transmit command to SD card SPI_transfer(cmd | 0x40); // Transmit argument SPI_transfer((uint8_t)(arg >> 24)); SPI_transfer((uint8_t)(arg >> 16)); SPI_transfer((uint8_t)(arg >> 8)); SPI_transfer((uint8_t)(arg)); // Transmit crc SPI_transfer(crc | 0x01); } uint8_t SD_readRes1() { uint8_t i = 0, res1; // Keep polling until actual data received while ((res1 = SPI_transfer(0xFF)) == 0xFF) { i++; // If no data received for 8 bytes, break if (i > 8) break; } return res1; } uint8_t SD_goIdleState() { // Assert chip select SPI_transfer(0xFF); CS_ENABLE(); SPI_transfer(0xFF); // Send CMD0 SD_command(0x40, 0x00000000, 0x95); // Read response uint8_t res1 = SD_readRes1(); // Deassert chip select SPI_transfer(0xFF); CS_DISABLE(); SPI_transfer(0xFF); return res1; } uint8_t SD_sendCmd8() { // Assert chip select SPI_transfer(0xFF); CS_ENABLE(); SPI_transfer(0xFF); // Send CMD8 with voltage range and check pattern SD_command(0x48, 0x000001AA, 0x87); // Read response uint8_t res1 = SD_readRes1(); // Deassert chip select SPI_transfer(0xFF); CS_DISABLE(); SPI_transfer(0xFF); return res1; } uint8_t SD_sendCmd58() { // Assert chip select SPI_transfer(0xFF); CS_ENABLE(); SPI_transfer(0xFF); // Send CMD58 SD_command(0x58, 0x00000000, 0x00); // Read response uint8_t res1 = SD_readRes1(); // Deassert chip select SPI_transfer(0xFF); CS_DISABLE(); SPI_transfer(0xFF); return res1; } uint8_t SD_sendAppCmd() { // Assert chip select SPI_transfer(0xFF); CS_ENABLE(); SPI_transfer(0xFF); // Send CMD55 (Application Command) SD_command(0x55, 0x00000000, 0x00); // Read response uint8_t res1 = SD_readRes1(); // Deassert chip select SPI_transfer(0xFF); CS_DISABLE(); SPI_transfer(0xFF); return res1; } uint8_t SD_sendOpCond() { // Assert chip select SPI_transfer(0xFF); CS_ENABLE(); SPI_transfer(0xFF); // Send ACMD41 (Send Operating Condition) SD_command(0x41, 0x40000000, 0x00); // Read response uint8_t res1 = SD_readRes1(); // Deassert chip select SPI_transfer(0xFF); CS_DISABLE(); SPI_transfer(0xFF); return res1; } FRESULT createFile() { FRESULT result; FIL file; // Open or create a file named "data.txt" result = f_open(&file, "data.txt", FA_CREATE_ALWAYS | FA_WRITE); if (result == FR_OK) { // File created successfully f_close(&file); return FR_OK; } else { // Error creating the file return result; } } FRESULT writeToFile(const char* data) { FRESULT result; FIL file; UINT bytesWritten; // Open the file for writing result = f_open(&file, "data.txt", FA_WRITE); if (result == FR_OK) { // Write data to the file result = f_write(&file, data, strlen(data), &bytesWritten); if (result == FR_OK) { // Data written successfully f_close(&file); return FR_OK; } } // Error writing data return result; } int main() { /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/ #ifdef PEX_RTOS_INIT PEX_RTOS_INIT(); /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */ #endif /*** End of Processor Expert internal initialization. ***/ // Initialize SPI SPI_init(); // Perform power-up sequence SD_powerUpSeq(); // Go to idle state uint8_t idleResponse = SD_goIdleState(); printf("Idle Response: %d\n", idleResponse); // Send CMD8 uint8_t cmd8Response = SD_sendCmd8(); printf("CMD8 Response: %d\n", cmd8Response); // Send CMD58 uint8_t cmd58Response = SD_sendCmd58(); printf("CMD58 Response: %d\n", cmd58Response); // Send CMD55 (Application Command) uint8_t cmd55Response = SD_sendAppCmd(); printf("CMD55 Response: %d\n", cmd55Response); // Send ACMD41 (Send Operating Condition) uint8_t acmd41Response = SD_sendOpCond(); printf("ACMD41 Response: %d\n", acmd41Response); // Create the file FRESULT createResult = createFile(); if (createResult == FR_OK) { printf("File created successfully.\n"); // Write data to the file const char* dataToWrite = "Hello, SD card!"; FRESULT writeResult = writeToFile(dataToWrite); if (writeResult == FR_OK) { printf("Data written to the file.\n"); } else { printf("Error writing data to the file: %d\n", writeResult); } } else { printf("Error creating file: %d\n", createResult); } /*** Don't write any code pass this line, or it will be deleted during code generation. ***/ /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/ #ifdef PEX_RTOS_START PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */ #endif /*** End of RTOS startup code. ***/ /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/ for(;;) { if(exit_code != 0) { break; } } return exit_code; /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/ }