SD card v7 BSP (#361)
* Outdated apps: add api-light-usage * Gpio: update SD card CS pin settings * API-power: added fns to disable/enable external 3v3 dc-dc * API-gpio: separated SD card detect routines * Resources: removed sd cs pin * SD card: low level init now resets card power supply * App SD-filesystem: use new card detect fns * SD card: fix low level init headers * SD card: more realilable low level init, power reset, exit from command read cycle conditionally * App SD-filesystem: led notifiers, init cycling * SD card: backport to F4 * SD card: handle eject in init sequence * SD card: api to set level on detect gpio * SPI: api to set state on bus pins * SD card: set low state on bus pins while power reset Co-authored-by: coreglitch <mail@s3f.ru>
This commit is contained in:
		
							parent
							
								
									3f10ce47f0
								
							
						
					
					
						commit
						fef16a8e7a
					
				| @ -4,6 +4,7 @@ | ||||
| #include "menu/menu.h" | ||||
| #include "menu/menu_item.h" | ||||
| #include "cli/cli.h" | ||||
| #include "api-hal-sd.h" | ||||
| 
 | ||||
| FS_Api* fs_api_alloc() { | ||||
|     FS_Api* fs_api = furi_alloc(sizeof(FS_Api)); | ||||
| @ -316,6 +317,95 @@ void app_sd_format_callback(void* context) { | ||||
|     view_port_enabled_set(sd_app->view_port, false); | ||||
| } | ||||
| 
 | ||||
| void app_sd_notify_wait_on() { | ||||
|     api_hal_light_set(LightRed, 0xFF); | ||||
|     api_hal_light_set(LightBlue, 0xFF); | ||||
| } | ||||
| 
 | ||||
| void app_sd_notify_wait_off() { | ||||
|     api_hal_light_set(LightRed, 0x00); | ||||
|     api_hal_light_set(LightBlue, 0x00); | ||||
| } | ||||
| 
 | ||||
| void app_sd_notify_success() { | ||||
|     for(uint8_t i = 0; i < 3; i++) { | ||||
|         delay(50); | ||||
|         api_hal_light_set(LightGreen, 0xFF); | ||||
|         delay(50); | ||||
|         api_hal_light_set(LightGreen, 0x00); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void app_sd_notify_eject() { | ||||
|     for(uint8_t i = 0; i < 3; i++) { | ||||
|         delay(50); | ||||
|         api_hal_light_set(LightBlue, 0xFF); | ||||
|         delay(50); | ||||
|         api_hal_light_set(LightBlue, 0x00); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void app_sd_notify_error() { | ||||
|     for(uint8_t i = 0; i < 3; i++) { | ||||
|         delay(50); | ||||
|         api_hal_light_set(LightRed, 0xFF); | ||||
|         delay(50); | ||||
|         api_hal_light_set(LightRed, 0x00); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool app_sd_mount_card(SdApp* sd_app) { | ||||
|     bool result = false; | ||||
|     const uint8_t max_init_counts = 10; | ||||
|     uint8_t counter = max_init_counts; | ||||
|     uint8_t bsp_result; | ||||
| 
 | ||||
|     _fs_lock(&sd_app->info); | ||||
| 
 | ||||
|     while(result == false && counter > 0 && hal_sd_detect()) { | ||||
|         app_sd_notify_wait_on(); | ||||
| 
 | ||||
|         if((counter % 10) == 0) { | ||||
|             // power reset sd card
 | ||||
|             bsp_result = BSP_SD_Init(true); | ||||
|         } else { | ||||
|             bsp_result = BSP_SD_Init(false); | ||||
|         } | ||||
| 
 | ||||
|         if(bsp_result) { | ||||
|             // bsp error
 | ||||
|             sd_app->info.status = SD_LOW_LEVEL_ERR; | ||||
|         } else { | ||||
|             sd_app->info.status = f_mount(&sd_app->info.fat_fs, sd_app->info.path, 1); | ||||
| 
 | ||||
|             if(sd_app->info.status == SD_OK || sd_app->info.status == SD_NO_FILESYSTEM) { | ||||
|                 FATFS* fs; | ||||
|                 uint32_t free_clusters; | ||||
| 
 | ||||
|                 sd_app->info.status = f_getfree(sd_app->info.path, &free_clusters, &fs); | ||||
| 
 | ||||
|                 if(sd_app->info.status == SD_OK || sd_app->info.status == SD_NO_FILESYSTEM) { | ||||
|                     result = true; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         app_sd_notify_wait_off(); | ||||
| 
 | ||||
|         if(!result) { | ||||
|             delay(1000); | ||||
|             printf( | ||||
|                 "[sd_filesystem] init(%d), error: %s\r\n", | ||||
|                 counter, | ||||
|                 fs_error_get_internal_desc(sd_app->info.status)); | ||||
| 
 | ||||
|             counter--; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     _fs_unlock(&sd_app->info); | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| void app_sd_unmount_card(SdApp* sd_app) { | ||||
|     _fs_lock(&sd_app->info); | ||||
| 
 | ||||
| @ -517,37 +607,44 @@ int32_t sd_filesystem(void* p) { | ||||
|     // sd card cycle
 | ||||
|     bool sd_was_present = true; | ||||
| 
 | ||||
|     // init detect pins
 | ||||
|     hal_sd_detect_init(); | ||||
| 
 | ||||
|     while(true) { | ||||
|         if(sd_was_present) { | ||||
|             if(hal_gpio_read_sd_detect()) { | ||||
|             if(hal_sd_detect()) { | ||||
|                 printf("[sd_filesystem] card detected\r\n"); | ||||
|                 app_sd_mount_card(sd_app); | ||||
| 
 | ||||
|                 uint8_t bsp_result = BSP_SD_Init(); | ||||
| 
 | ||||
|                 if(bsp_result) { | ||||
|                     sd_app->info.status = SD_LOW_LEVEL_ERR; | ||||
|                     printf("[sd_filesystem] bsp error: %x\n", bsp_result); | ||||
|                 if(sd_app->info.status != SD_OK) { | ||||
|                     printf( | ||||
|                         "[sd_filesystem] sd init error: %s\r\n", | ||||
|                         fs_error_get_internal_desc(sd_app->info.status)); | ||||
|                     app_sd_notify_error(); | ||||
|                 } else { | ||||
|                     printf("[sd_filesystem] bsp ok\r\n"); | ||||
|                     sd_app->info.status = f_mount(&sd_app->info.fat_fs, sd_app->info.path, 1); | ||||
| 
 | ||||
|                     if(sd_app->info.status != SD_OK) { | ||||
|                         printf("[sd_filesystem] mount error: %d\n", sd_app->info.status); | ||||
|                     } else { | ||||
|                         printf("[sd_filesystem] mount ok\r\n"); | ||||
|                     } | ||||
|                     printf("[sd_filesystem] sd init ok\r\n"); | ||||
|                     app_sd_notify_success(); | ||||
|                 } | ||||
| 
 | ||||
|                 view_port_enabled_set(sd_app->icon.view_port, true); | ||||
|                 sd_was_present = false; | ||||
| 
 | ||||
|                 if(!hal_sd_detect()) { | ||||
|                     printf("[sd_filesystem] card removed\r\n"); | ||||
| 
 | ||||
|                     view_port_enabled_set(sd_app->icon.view_port, false); | ||||
|                     app_sd_unmount_card(sd_app); | ||||
|                     sd_was_present = true; | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             if(!hal_gpio_read_sd_detect()) { | ||||
|             if(!hal_sd_detect()) { | ||||
|                 printf("[sd_filesystem] card removed\r\n"); | ||||
| 
 | ||||
|                 view_port_enabled_set(sd_app->icon.view_port, false); | ||||
|                 app_sd_unmount_card(sd_app); | ||||
|                 sd_was_present = true; | ||||
|                 app_sd_notify_eject(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -83,6 +83,16 @@ float api_hal_power_get_usb_voltage(); | ||||
| /* Get power system component state */ | ||||
| void api_hal_power_dump_state(string_t buffer); | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Enable 3.3v on external gpio and sd card | ||||
|  */ | ||||
| void api_hal_power_enable_external_3_3v(); | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Disable 3.3v on external gpio and sd card | ||||
|  */ | ||||
| void api_hal_power_disable_external_3_3v(); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										30
									
								
								firmware/targets/api-hal-include/api-hal-sd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								firmware/targets/api-hal-include/api-hal-sd.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Init SD card detect | ||||
|  *  | ||||
|  */ | ||||
| void hal_sd_detect_init(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Set SD card detect pin to low | ||||
|  *  | ||||
|  */ | ||||
| void hal_sd_detect_set_low(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Get SD card status | ||||
|  *  | ||||
|  * @return true if SD card present | ||||
|  * @return false if SD card not present | ||||
|  */ | ||||
| bool hal_sd_detect(void); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| @ -92,7 +92,9 @@ | ||||
| #include "string.h" | ||||
| #include "stdio.h" | ||||
| #include "spi.h" | ||||
| #include "api-hal-spi.h" | ||||
| #include <api-hal-spi.h> | ||||
| #include <api-hal-power.h> | ||||
| #include <api-hal-delay.h> | ||||
| 
 | ||||
| /** @addtogroup BSP
 | ||||
|   * @{ | ||||
| @ -290,19 +292,33 @@ static uint8_t SD_ReadData(void); | ||||
|   *         - MSD_ERROR: Sequence failed | ||||
|   *         - MSD_OK: Sequence succeed | ||||
|   */ | ||||
| uint8_t BSP_SD_Init(void) { | ||||
|     /* Init to maximum slow speed */ | ||||
|     // TODO: SPI manager
 | ||||
| uint8_t BSP_SD_Init(bool reset_card) { | ||||
|     /* Slow speed init */ | ||||
| 
 | ||||
|     /* TODO: SPI manager */ | ||||
|     api_hal_spi_lock_device(&sd_slow_spi); | ||||
| 
 | ||||
|     /* We must reset card in spi_lock context */ | ||||
|     if(reset_card) { | ||||
|         api_hal_power_disable_external_3_3v(); | ||||
|         delay(100); | ||||
|         api_hal_power_enable_external_3_3v(); | ||||
|         delay(100); | ||||
|     } | ||||
| 
 | ||||
|     /* Configure IO functionalities for SD pin */ | ||||
|     SD_IO_Init(); | ||||
| 
 | ||||
|     /* SD detection pin is not physically mapped on the Adafruit shield */ | ||||
|     SdStatus = SD_PRESENT; | ||||
|     uint8_t res = SD_GoIdleState(); | ||||
|     uint8_t res = BSP_SD_ERROR; | ||||
| 
 | ||||
|     // TODO: SPI manager
 | ||||
|     for(uint8_t i = 0; i < 128; i++) { | ||||
|         res = SD_GoIdleState(); | ||||
|         if(res == BSP_SD_OK) break; | ||||
|     } | ||||
| 
 | ||||
|     /* TODO: SPI manager */ | ||||
|     api_hal_spi_unlock_device(&sd_slow_spi); | ||||
| 
 | ||||
|     /* SD initialized and set to SPI mode properly */ | ||||
| @ -872,9 +888,10 @@ uint8_t SD_GetDataResponse(void) { | ||||
|   */ | ||||
| uint8_t SD_GoIdleState(void) { | ||||
|     SD_CmdAnswer_typedef response; | ||||
|     __IO uint8_t counter = 0; | ||||
|     __IO uint8_t counter; | ||||
|     /* Send CMD0 (SD_CMD_GO_IDLE_STATE) to put SD in SPI mode and 
 | ||||
|      wait for In Idle State Response (R1 Format) equal to 0x01 */ | ||||
|     counter = 0; | ||||
|     do { | ||||
|         counter++; | ||||
|         response = SD_SendCmd(SD_CMD_GO_IDLE_STATE, 0, 0x95, SD_ANSWER_R1_EXPECTED); | ||||
| @ -892,7 +909,9 @@ uint8_t SD_GoIdleState(void) { | ||||
|     SD_IO_WriteByte(SD_DUMMY_BYTE); | ||||
|     if((response.r1 & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND) { | ||||
|         /* initialise card V1 */ | ||||
|         counter = 0; | ||||
|         do { | ||||
|             counter++; | ||||
|             /* initialise card V1 */ | ||||
|             /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ | ||||
|             response = SD_SendCmd(SD_CMD_APP_CMD, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); | ||||
| @ -903,11 +922,16 @@ uint8_t SD_GoIdleState(void) { | ||||
|             response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); | ||||
|             SD_IO_CSState(1); | ||||
|             SD_IO_WriteByte(SD_DUMMY_BYTE); | ||||
|             if(counter >= SD_MAX_TRY) { | ||||
|                 return BSP_SD_ERROR; | ||||
|             } | ||||
|         } while(response.r1 == SD_R1_IN_IDLE_STATE); | ||||
|         flag_SDHC = 0; | ||||
|     } else if(response.r1 == SD_R1_IN_IDLE_STATE) { | ||||
|         /* initialise card V2 */ | ||||
|         counter = 0; | ||||
|         do { | ||||
|             counter++; | ||||
|             /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ | ||||
|             response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED); | ||||
|             SD_IO_CSState(1); | ||||
| @ -917,10 +941,15 @@ uint8_t SD_GoIdleState(void) { | ||||
|             response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x40000000, 0xFF, SD_ANSWER_R1_EXPECTED); | ||||
|             SD_IO_CSState(1); | ||||
|             SD_IO_WriteByte(SD_DUMMY_BYTE); | ||||
|             if(counter >= SD_MAX_TRY) { | ||||
|                 return BSP_SD_ERROR; | ||||
|             } | ||||
|         } while(response.r1 == SD_R1_IN_IDLE_STATE); | ||||
| 
 | ||||
|         if((response.r1 & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND) { | ||||
|             counter = 0; | ||||
|             do { | ||||
|                 counter++; | ||||
|                 /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ | ||||
|                 response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED); | ||||
|                 SD_IO_CSState(1); | ||||
| @ -933,6 +962,9 @@ uint8_t SD_GoIdleState(void) { | ||||
|                     SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); | ||||
|                 SD_IO_CSState(1); | ||||
|                 SD_IO_WriteByte(SD_DUMMY_BYTE); | ||||
|                 if(counter >= SD_MAX_TRY) { | ||||
|                     return BSP_SD_ERROR; | ||||
|                 } | ||||
|             } while(response.r1 == SD_R1_IN_IDLE_STATE); | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -41,16 +41,17 @@ | ||||
| #define __STM32_ADAFRUIT_SD_H | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
|  extern "C" { | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| /* Includes ------------------------------------------------------------------*/ | ||||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| /** @addtogroup BSP
 | ||||
|   * @{ | ||||
|   */ | ||||
| #define __IO    volatile    | ||||
| #define __IO volatile | ||||
| 
 | ||||
| /** @addtogroup STM32_ADAFRUIT
 | ||||
|   * @{ | ||||
| @ -67,104 +68,93 @@ | ||||
| /** 
 | ||||
|   * @brief  SD status structure definition   | ||||
|   */ | ||||
| enum {     | ||||
|       BSP_SD_OK = 0x00,       | ||||
|       MSD_OK = 0x00, | ||||
|       BSP_SD_ERROR = 0x01, | ||||
|       BSP_SD_TIMEOUT | ||||
| }; | ||||
| enum { BSP_SD_OK = 0x00, MSD_OK = 0x00, BSP_SD_ERROR = 0x01, BSP_SD_TIMEOUT }; | ||||
| 
 | ||||
| typedef struct               | ||||
| { | ||||
|   uint8_t  Reserved1:2;               /* Reserved */ | ||||
|   uint16_t DeviceSize:12;             /* Device Size */ | ||||
|   uint8_t  MaxRdCurrentVDDMin:3;      /* Max. read current @ VDD min */ | ||||
|   uint8_t  MaxRdCurrentVDDMax:3;      /* Max. read current @ VDD max */ | ||||
|   uint8_t  MaxWrCurrentVDDMin:3;      /* Max. write current @ VDD min */ | ||||
|   uint8_t  MaxWrCurrentVDDMax:3;      /* Max. write current @ VDD max */ | ||||
|   uint8_t  DeviceSizeMul:3;           /* Device size multiplier */ | ||||
| typedef struct { | ||||
|     uint8_t Reserved1 : 2; /* Reserved */ | ||||
|     uint16_t DeviceSize : 12; /* Device Size */ | ||||
|     uint8_t MaxRdCurrentVDDMin : 3; /* Max. read current @ VDD min */ | ||||
|     uint8_t MaxRdCurrentVDDMax : 3; /* Max. read current @ VDD max */ | ||||
|     uint8_t MaxWrCurrentVDDMin : 3; /* Max. write current @ VDD min */ | ||||
|     uint8_t MaxWrCurrentVDDMax : 3; /* Max. write current @ VDD max */ | ||||
|     uint8_t DeviceSizeMul : 3; /* Device size multiplier */ | ||||
| } struct_v1; | ||||
| 
 | ||||
| 
 | ||||
| typedef struct               | ||||
| { | ||||
|   uint8_t  Reserved1:6;               /* Reserved */ | ||||
|   uint32_t DeviceSize:22;             /* Device Size */ | ||||
|   uint8_t  Reserved2:1;               /* Reserved */ | ||||
| typedef struct { | ||||
|     uint8_t Reserved1 : 6; /* Reserved */ | ||||
|     uint32_t DeviceSize : 22; /* Device Size */ | ||||
|     uint8_t Reserved2 : 1; /* Reserved */ | ||||
| } struct_v2; | ||||
| 
 | ||||
| /** 
 | ||||
|   * @brief  Card Specific Data: CSD Register | ||||
|   */ | ||||
| typedef struct | ||||
| { | ||||
|   /* Header part */ | ||||
|   uint8_t  CSDStruct:2;            /* CSD structure */ | ||||
|   uint8_t  Reserved1:6;            /* Reserved */ | ||||
|   uint8_t  TAAC:8;                 /* Data read access-time 1 */ | ||||
|   uint8_t  NSAC:8;                 /* Data read access-time 2 in CLK cycles */ | ||||
|   uint8_t  MaxBusClkFrec:8;        /* Max. bus clock frequency */ | ||||
|   uint16_t CardComdClasses:12;      /* Card command classes */ | ||||
|   uint8_t  RdBlockLen:4;           /* Max. read data block length */ | ||||
|   uint8_t  PartBlockRead:1;        /* Partial blocks for read allowed */ | ||||
|   uint8_t  WrBlockMisalign:1;      /* Write block misalignment */ | ||||
|   uint8_t  RdBlockMisalign:1;      /* Read block misalignment */ | ||||
|   uint8_t  DSRImpl:1;              /* DSR implemented */ | ||||
| typedef struct { | ||||
|     /* Header part */ | ||||
|     uint8_t CSDStruct : 2; /* CSD structure */ | ||||
|     uint8_t Reserved1 : 6; /* Reserved */ | ||||
|     uint8_t TAAC : 8; /* Data read access-time 1 */ | ||||
|     uint8_t NSAC : 8; /* Data read access-time 2 in CLK cycles */ | ||||
|     uint8_t MaxBusClkFrec : 8; /* Max. bus clock frequency */ | ||||
|     uint16_t CardComdClasses : 12; /* Card command classes */ | ||||
|     uint8_t RdBlockLen : 4; /* Max. read data block length */ | ||||
|     uint8_t PartBlockRead : 1; /* Partial blocks for read allowed */ | ||||
|     uint8_t WrBlockMisalign : 1; /* Write block misalignment */ | ||||
|     uint8_t RdBlockMisalign : 1; /* Read block misalignment */ | ||||
|     uint8_t DSRImpl : 1; /* DSR implemented */ | ||||
| 
 | ||||
|   /* v1 or v2 struct */ | ||||
|   union csd_version { | ||||
|     struct_v1 v1; | ||||
|     struct_v2 v2; | ||||
|   } version; | ||||
|     /* v1 or v2 struct */ | ||||
|     union csd_version { | ||||
|         struct_v1 v1; | ||||
|         struct_v2 v2; | ||||
|     } version; | ||||
| 
 | ||||
|   uint8_t  EraseSingleBlockEnable:1;  /* Erase single block enable */ | ||||
|   uint8_t  EraseSectorSize:7;         /* Erase group size multiplier */ | ||||
|   uint8_t  WrProtectGrSize:7;         /* Write protect group size */ | ||||
|   uint8_t  WrProtectGrEnable:1;       /* Write protect group enable */ | ||||
|   uint8_t  Reserved2:2;               /* Reserved */ | ||||
|   uint8_t  WrSpeedFact:3;             /* Write speed factor */ | ||||
|   uint8_t  MaxWrBlockLen:4;           /* Max. write data block length */ | ||||
|   uint8_t  WriteBlockPartial:1;       /* Partial blocks for write allowed */ | ||||
|   uint8_t  Reserved3:5;               /* Reserved */ | ||||
|   uint8_t  FileFormatGrouop:1;        /* File format group */ | ||||
|   uint8_t  CopyFlag:1;                /* Copy flag (OTP) */ | ||||
|   uint8_t  PermWrProtect:1;           /* Permanent write protection */ | ||||
|   uint8_t  TempWrProtect:1;           /* Temporary write protection */ | ||||
|   uint8_t  FileFormat:2;              /* File Format */ | ||||
|   uint8_t  Reserved4:2;               /* Reserved */ | ||||
|   uint8_t  crc:7;                     /* Reserved */ | ||||
|   uint8_t  Reserved5:1;               /* always 1*/ | ||||
|     uint8_t EraseSingleBlockEnable : 1; /* Erase single block enable */ | ||||
|     uint8_t EraseSectorSize : 7; /* Erase group size multiplier */ | ||||
|     uint8_t WrProtectGrSize : 7; /* Write protect group size */ | ||||
|     uint8_t WrProtectGrEnable : 1; /* Write protect group enable */ | ||||
|     uint8_t Reserved2 : 2; /* Reserved */ | ||||
|     uint8_t WrSpeedFact : 3; /* Write speed factor */ | ||||
|     uint8_t MaxWrBlockLen : 4; /* Max. write data block length */ | ||||
|     uint8_t WriteBlockPartial : 1; /* Partial blocks for write allowed */ | ||||
|     uint8_t Reserved3 : 5; /* Reserved */ | ||||
|     uint8_t FileFormatGrouop : 1; /* File format group */ | ||||
|     uint8_t CopyFlag : 1; /* Copy flag (OTP) */ | ||||
|     uint8_t PermWrProtect : 1; /* Permanent write protection */ | ||||
|     uint8_t TempWrProtect : 1; /* Temporary write protection */ | ||||
|     uint8_t FileFormat : 2; /* File Format */ | ||||
|     uint8_t Reserved4 : 2; /* Reserved */ | ||||
|     uint8_t crc : 7; /* Reserved */ | ||||
|     uint8_t Reserved5 : 1; /* always 1*/ | ||||
| 
 | ||||
| } SD_CSD; | ||||
| 
 | ||||
| /** 
 | ||||
|   * @brief  Card Identification Data: CID Register    | ||||
|   */ | ||||
| typedef struct | ||||
| { | ||||
|   __IO uint8_t  ManufacturerID;       /* ManufacturerID */ | ||||
|   __IO uint16_t OEM_AppliID;          /* OEM/Application ID */ | ||||
|   __IO uint32_t ProdName1;            /* Product Name part1 */ | ||||
|   __IO uint8_t  ProdName2;            /* Product Name part2*/ | ||||
|   __IO uint8_t  ProdRev;              /* Product Revision */ | ||||
|   __IO uint32_t ProdSN;               /* Product Serial Number */ | ||||
|   __IO uint8_t  Reserved1;            /* Reserved1 */ | ||||
|   __IO uint16_t ManufactDate;         /* Manufacturing Date */ | ||||
|   __IO uint8_t  CID_CRC;              /* CID CRC */ | ||||
|   __IO uint8_t  Reserved2;            /* always 1 */ | ||||
| typedef struct { | ||||
|     __IO uint8_t ManufacturerID; /* ManufacturerID */ | ||||
|     __IO uint16_t OEM_AppliID; /* OEM/Application ID */ | ||||
|     __IO uint32_t ProdName1; /* Product Name part1 */ | ||||
|     __IO uint8_t ProdName2; /* Product Name part2*/ | ||||
|     __IO uint8_t ProdRev; /* Product Revision */ | ||||
|     __IO uint32_t ProdSN; /* Product Serial Number */ | ||||
|     __IO uint8_t Reserved1; /* Reserved1 */ | ||||
|     __IO uint16_t ManufactDate; /* Manufacturing Date */ | ||||
|     __IO uint8_t CID_CRC; /* CID CRC */ | ||||
|     __IO uint8_t Reserved2; /* always 1 */ | ||||
| } SD_CID; | ||||
| 
 | ||||
| /** 
 | ||||
|   * @brief SD Card information  | ||||
|   */ | ||||
| typedef struct | ||||
| { | ||||
|   SD_CSD Csd; | ||||
|   SD_CID Cid; | ||||
|   uint64_t CardCapacity;              /*!< Card Capacity */ | ||||
|   uint32_t CardBlockSize;             /*!< Card Block Size */ | ||||
|   uint32_t LogBlockNbr;               /*!< Specifies the Card logical Capacity in blocks   */ | ||||
|   uint32_t LogBlockSize;              /*!< Specifies logical block size in bytes           */ | ||||
| typedef struct { | ||||
|     SD_CSD Csd; | ||||
|     SD_CID Cid; | ||||
|     uint64_t CardCapacity; /*!< Card Capacity */ | ||||
|     uint32_t CardBlockSize; /*!< Card Block Size */ | ||||
|     uint32_t LogBlockNbr; /*!< Specifies the Card logical Capacity in blocks   */ | ||||
|     uint32_t LogBlockSize; /*!< Specifies logical block size in bytes           */ | ||||
| } SD_CardInfo; | ||||
| 
 | ||||
| /**
 | ||||
| @ -178,15 +168,15 @@ typedef struct | ||||
| /**
 | ||||
|   * @brief  Block Size | ||||
|   */ | ||||
| #define SD_BLOCK_SIZE    0x200 | ||||
| #define SD_BLOCK_SIZE 0x200 | ||||
| 
 | ||||
| /**
 | ||||
|   * @brief  SD detection on its memory slot | ||||
|   */ | ||||
| #define SD_PRESENT               ((uint8_t)0x01) | ||||
| #define SD_NOT_PRESENT           ((uint8_t)0x00) | ||||
| #define SD_PRESENT ((uint8_t)0x01) | ||||
| #define SD_NOT_PRESENT ((uint8_t)0x00) | ||||
| 
 | ||||
| #define SD_DATATIMEOUT           ((uint32_t)100000000) | ||||
| #define SD_DATATIMEOUT ((uint32_t)100000000) | ||||
| 
 | ||||
| /** 
 | ||||
|   * @brief SD Card information structure  | ||||
| @ -208,19 +198,21 @@ typedef struct | ||||
| /** @defgroup STM32_ADAFRUIT_SD_Exported_Functions
 | ||||
|   * @{ | ||||
|   */ | ||||
| uint8_t BSP_SD_Init(void); | ||||
| uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout); | ||||
| uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout); | ||||
| uint8_t BSP_SD_Init(bool reset_card); | ||||
| uint8_t | ||||
| BSP_SD_ReadBlocks(uint32_t* pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout); | ||||
| uint8_t | ||||
| BSP_SD_WriteBlocks(uint32_t* pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout); | ||||
| uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr); | ||||
| uint8_t BSP_SD_GetCardState(void); | ||||
| uint8_t BSP_SD_GetCardInfo(SD_CardInfo *pCardInfo); | ||||
| uint8_t BSP_SD_GetCardInfo(SD_CardInfo* pCardInfo); | ||||
| 
 | ||||
| /* Link functions for SD Card peripheral*/ | ||||
| void    SD_SPI_Slow_Init(void); | ||||
| void    SD_SPI_Fast_Init(void); | ||||
| void    SD_IO_Init(void); | ||||
| void    SD_IO_CSState(uint8_t state); | ||||
| void    SD_IO_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLength); | ||||
| void SD_SPI_Slow_Init(void); | ||||
| void SD_SPI_Fast_Init(void); | ||||
| void SD_IO_Init(void); | ||||
| void SD_IO_CSState(uint8_t state); | ||||
| void SD_IO_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t DataLength); | ||||
| uint8_t SD_IO_WriteByte(uint8_t Data); | ||||
| 
 | ||||
| /* Link function for HAL delay */ | ||||
|  | ||||
| @ -1,7 +1,4 @@ | ||||
| #include <api-hal-gpio.h> | ||||
| #include <api-hal-spi.h> | ||||
| #include <api-hal-resources.h> | ||||
| #include <api-hal-delay.h> | ||||
| 
 | ||||
| // init GPIO
 | ||||
| void hal_gpio_init( | ||||
| @ -20,33 +17,6 @@ void hal_gpio_init( | ||||
|     HAL_GPIO_Init(gpio->port, &GPIO_InitStruct); | ||||
| } | ||||
| 
 | ||||
| bool hal_gpio_read_sd_detect(void) { | ||||
|     bool result = false; | ||||
| 
 | ||||
|     // TODO open record
 | ||||
|     const GpioPin* sd_cs_record = &sd_cs_gpio; | ||||
| 
 | ||||
|     // TODO: SPI manager
 | ||||
|     api_hal_spi_lock(sd_fast_spi.spi); | ||||
| 
 | ||||
|     // configure pin as input
 | ||||
|     gpio_init_ex(sd_cs_record, GpioModeInput, GpioPullUp, GpioSpeedVeryHigh); | ||||
|     delay(1); | ||||
| 
 | ||||
|     // if gpio_read == 0 return true else return false
 | ||||
|     result = !gpio_read(sd_cs_record); | ||||
| 
 | ||||
|     // configure pin back
 | ||||
|     gpio_init_ex(sd_cs_record, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); | ||||
|     gpio_write(sd_cs_record, 1); | ||||
|     delay(1); | ||||
| 
 | ||||
|     // TODO: SPI manager
 | ||||
|     api_hal_spi_unlock(sd_fast_spi.spi); | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| void enable_cc1101_irq() { | ||||
|     HAL_NVIC_SetPriority(EXTI4_IRQn, 5, 0); | ||||
|     HAL_NVIC_EnableIRQ(EXTI4_IRQn); | ||||
|  | ||||
| @ -68,8 +68,6 @@ static inline bool hal_gpio_read(const GpioPin* gpio) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool hal_gpio_read_sd_detect(void); | ||||
| 
 | ||||
| void enable_cc1101_irq(); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
|  | ||||
| @ -195,3 +195,11 @@ void api_hal_power_dump_state(string_t buffer) { | ||||
|         bq25896_get_ntc_mpct() | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| void api_hal_power_enable_external_3_3v(){ | ||||
|     // nothing to do
 | ||||
| } | ||||
| 
 | ||||
| void api_hal_power_disable_external_3_3v(){ | ||||
|     // nothing to do
 | ||||
| } | ||||
							
								
								
									
										40
									
								
								firmware/targets/f4/api-hal/api-hal-sd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								firmware/targets/f4/api-hal/api-hal-sd.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| #include <api-hal-sd.h> | ||||
| #include <api-hal-spi.h> | ||||
| #include <api-hal-resources.h> | ||||
| #include <api-hal-delay.h> | ||||
| #include <furi.h> | ||||
| 
 | ||||
| void hal_sd_detect_init(void) { | ||||
|     // nothing to do
 | ||||
| } | ||||
| 
 | ||||
| void hal_sd_detect_set_low(void) { | ||||
|     // nothing to do
 | ||||
| } | ||||
| 
 | ||||
| bool hal_sd_detect(void) { | ||||
|     bool result = false; | ||||
| 
 | ||||
|     // TODO open record
 | ||||
|     const GpioPin* sd_cs_record = &sd_cs_gpio; | ||||
| 
 | ||||
|     // TODO: SPI manager
 | ||||
|     api_hal_spi_lock(sd_fast_spi.spi); | ||||
| 
 | ||||
|     // configure pin as input
 | ||||
|     gpio_init_ex(sd_cs_record, GpioModeInput, GpioPullUp, GpioSpeedVeryHigh); | ||||
|     delay(1); | ||||
| 
 | ||||
|     // if gpio_read == 0 return true else return false
 | ||||
|     result = !gpio_read(sd_cs_record); | ||||
| 
 | ||||
|     // configure pin back
 | ||||
|     gpio_init_ex(sd_cs_record, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); | ||||
|     gpio_write(sd_cs_record, 1); | ||||
|     delay(1); | ||||
| 
 | ||||
|     // TODO: SPI manager
 | ||||
|     api_hal_spi_unlock(sd_fast_spi.spi); | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| @ -46,6 +46,8 @@ void NFC_SPI_Reconfigure(); | ||||
| void SD_SPI_Reconfigure_Slow(); | ||||
| void SD_SPI_Reconfigure_Fast(); | ||||
| void CC1101_SPI_Reconfigure(); | ||||
| void SD_SPI_Bus_To_Down_State(); | ||||
| void SD_SPI_Bus_To_Normal_State(); | ||||
| /* USER CODE END Prototypes */ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
|  | ||||
| @ -92,7 +92,10 @@ | ||||
| #include "string.h" | ||||
| #include "stdio.h" | ||||
| #include "spi.h" | ||||
| #include "api-hal-spi.h" | ||||
| #include <api-hal-spi.h> | ||||
| #include <api-hal-power.h> | ||||
| #include <api-hal-delay.h> | ||||
| #include <api-hal-sd.h> | ||||
| 
 | ||||
| /** @addtogroup BSP
 | ||||
|   * @{ | ||||
| @ -290,19 +293,40 @@ static uint8_t SD_ReadData(void); | ||||
|   *         - MSD_ERROR: Sequence failed | ||||
|   *         - MSD_OK: Sequence succeed | ||||
|   */ | ||||
| uint8_t BSP_SD_Init(void) { | ||||
|     /* Init to maximum slow speed */ | ||||
|     // TODO: SPI manager
 | ||||
| uint8_t BSP_SD_Init(bool reset_card) { | ||||
|     /* Slow speed init */ | ||||
| 
 | ||||
|     /* TODO: SPI manager */ | ||||
|     api_hal_spi_lock_device(&sd_slow_spi); | ||||
| 
 | ||||
|     /* We must reset card in spi_lock context */ | ||||
|     if(reset_card) { | ||||
|         /* disable power and set low on all bus pins */ | ||||
|         api_hal_power_disable_external_3_3v(); | ||||
|         SD_SPI_Bus_To_Down_State(); | ||||
|         hal_sd_detect_set_low(); | ||||
|         delay(250); | ||||
| 
 | ||||
|         /* reinit bus and enable power */ | ||||
|         SD_SPI_Bus_To_Normal_State(); | ||||
|         hal_sd_detect_init(); | ||||
|         api_hal_power_enable_external_3_3v(); | ||||
|         delay(100); | ||||
|     } | ||||
| 
 | ||||
|     /* Configure IO functionalities for SD pin */ | ||||
|     SD_IO_Init(); | ||||
| 
 | ||||
|     /* SD detection pin is not physically mapped on the Adafruit shield */ | ||||
|     SdStatus = SD_PRESENT; | ||||
|     uint8_t res = SD_GoIdleState(); | ||||
|     uint8_t res = BSP_SD_ERROR; | ||||
| 
 | ||||
|     // TODO: SPI manager
 | ||||
|     for(uint8_t i = 0; i < 128; i++) { | ||||
|         res = SD_GoIdleState(); | ||||
|         if(res == BSP_SD_OK) break; | ||||
|     } | ||||
| 
 | ||||
|     /* TODO: SPI manager */ | ||||
|     api_hal_spi_unlock_device(&sd_slow_spi); | ||||
| 
 | ||||
|     /* SD initialized and set to SPI mode properly */ | ||||
| @ -872,9 +896,10 @@ uint8_t SD_GetDataResponse(void) { | ||||
|   */ | ||||
| uint8_t SD_GoIdleState(void) { | ||||
|     SD_CmdAnswer_typedef response; | ||||
|     __IO uint8_t counter = 0; | ||||
|     __IO uint8_t counter; | ||||
|     /* Send CMD0 (SD_CMD_GO_IDLE_STATE) to put SD in SPI mode and 
 | ||||
|      wait for In Idle State Response (R1 Format) equal to 0x01 */ | ||||
|     counter = 0; | ||||
|     do { | ||||
|         counter++; | ||||
|         response = SD_SendCmd(SD_CMD_GO_IDLE_STATE, 0, 0x95, SD_ANSWER_R1_EXPECTED); | ||||
| @ -892,7 +917,9 @@ uint8_t SD_GoIdleState(void) { | ||||
|     SD_IO_WriteByte(SD_DUMMY_BYTE); | ||||
|     if((response.r1 & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND) { | ||||
|         /* initialise card V1 */ | ||||
|         counter = 0; | ||||
|         do { | ||||
|             counter++; | ||||
|             /* initialise card V1 */ | ||||
|             /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ | ||||
|             response = SD_SendCmd(SD_CMD_APP_CMD, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); | ||||
| @ -903,11 +930,16 @@ uint8_t SD_GoIdleState(void) { | ||||
|             response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); | ||||
|             SD_IO_CSState(1); | ||||
|             SD_IO_WriteByte(SD_DUMMY_BYTE); | ||||
|             if(counter >= SD_MAX_TRY) { | ||||
|                 return BSP_SD_ERROR; | ||||
|             } | ||||
|         } while(response.r1 == SD_R1_IN_IDLE_STATE); | ||||
|         flag_SDHC = 0; | ||||
|     } else if(response.r1 == SD_R1_IN_IDLE_STATE) { | ||||
|         /* initialise card V2 */ | ||||
|         counter = 0; | ||||
|         do { | ||||
|             counter++; | ||||
|             /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ | ||||
|             response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED); | ||||
|             SD_IO_CSState(1); | ||||
| @ -917,10 +949,15 @@ uint8_t SD_GoIdleState(void) { | ||||
|             response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x40000000, 0xFF, SD_ANSWER_R1_EXPECTED); | ||||
|             SD_IO_CSState(1); | ||||
|             SD_IO_WriteByte(SD_DUMMY_BYTE); | ||||
|             if(counter >= SD_MAX_TRY) { | ||||
|                 return BSP_SD_ERROR; | ||||
|             } | ||||
|         } while(response.r1 == SD_R1_IN_IDLE_STATE); | ||||
| 
 | ||||
|         if((response.r1 & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND) { | ||||
|             counter = 0; | ||||
|             do { | ||||
|                 counter++; | ||||
|                 /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ | ||||
|                 response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED); | ||||
|                 SD_IO_CSState(1); | ||||
| @ -933,6 +970,9 @@ uint8_t SD_GoIdleState(void) { | ||||
|                     SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); | ||||
|                 SD_IO_CSState(1); | ||||
|                 SD_IO_WriteByte(SD_DUMMY_BYTE); | ||||
|                 if(counter >= SD_MAX_TRY) { | ||||
|                     return BSP_SD_ERROR; | ||||
|                 } | ||||
|             } while(response.r1 == SD_R1_IN_IDLE_STATE); | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -46,6 +46,7 @@ | ||||
| 
 | ||||
| /* Includes ------------------------------------------------------------------*/ | ||||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| /** @addtogroup BSP
 | ||||
|   * @{ | ||||
| @ -208,7 +209,7 @@ typedef struct | ||||
| /** @defgroup STM32_ADAFRUIT_SD_Exported_Functions
 | ||||
|   * @{ | ||||
|   */    | ||||
| uint8_t BSP_SD_Init(void); | ||||
| uint8_t BSP_SD_Init(bool reset_card); | ||||
| uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout); | ||||
| uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout); | ||||
| uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr); | ||||
|  | ||||
| @ -163,10 +163,9 @@ void MX_GPIO_Init(void) | ||||
| 
 | ||||
|   /*Configure GPIO pin : PtPin */ | ||||
|   GPIO_InitStruct.Pin = SD_CS_Pin; | ||||
|   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; | ||||
|   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; | ||||
|   GPIO_InitStruct.Pull = GPIO_NOPULL; | ||||
|   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; | ||||
|   GPIO_InitStruct.Alternate = GPIO_AF6_LSCO; | ||||
|   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; | ||||
|   HAL_GPIO_Init(SD_CS_GPIO_Port, &GPIO_InitStruct); | ||||
| 
 | ||||
|   /*Configure GPIO pin : PtPin */ | ||||
|  | ||||
| @ -339,6 +339,36 @@ void Enable_SPI(SPI_HandleTypeDef* spi_instance){ | ||||
|     __HAL_SPI_ENABLE(spi_instance); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void SD_SPI_Bus_To_Down_State(){ | ||||
|   GPIO_InitTypeDef GPIO_InitStruct = {0}; | ||||
|   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; | ||||
| 
 | ||||
|   GPIO_InitStruct.Pin = GPIO_PIN_2; | ||||
|   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; | ||||
|   GPIO_InitStruct.Pull = GPIO_NOPULL; | ||||
|   HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); | ||||
| 
 | ||||
|   GPIO_InitStruct.Pin = SPI_D_MOSI_Pin; | ||||
|   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; | ||||
|   GPIO_InitStruct.Pull = GPIO_NOPULL; | ||||
|   HAL_GPIO_Init(SPI_D_MOSI_GPIO_Port, &GPIO_InitStruct); | ||||
| 
 | ||||
|   GPIO_InitStruct.Pin = SPI_D_SCK_Pin; | ||||
|   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; | ||||
|   GPIO_InitStruct.Pull = GPIO_NOPULL; | ||||
|   HAL_GPIO_Init(SPI_D_SCK_GPIO_Port, &GPIO_InitStruct); | ||||
| 
 | ||||
|   HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_RESET); | ||||
|   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET); | ||||
|   HAL_GPIO_WritePin(SPI_D_MOSI_GPIO_Port, SPI_D_MOSI_Pin, GPIO_PIN_RESET); | ||||
|   HAL_GPIO_WritePin(SPI_D_SCK_GPIO_Port, SPI_D_SCK_Pin, GPIO_PIN_RESET); | ||||
| } | ||||
| 
 | ||||
| void SD_SPI_Bus_To_Normal_State(){ | ||||
|   HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_SET); | ||||
|   HAL_SPI_MspInit(&SPI_SD_HANDLE); | ||||
| } | ||||
| /* USER CODE END 1 */ | ||||
| 
 | ||||
| /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||
|  | ||||
| @ -20,33 +20,6 @@ void hal_gpio_init( | ||||
|     HAL_GPIO_Init(gpio->port, &GPIO_InitStruct); | ||||
| } | ||||
| 
 | ||||
| bool hal_gpio_read_sd_detect(void) { | ||||
|     bool result = false; | ||||
| 
 | ||||
|     // TODO open record
 | ||||
|     const GpioPin* sd_cs_record = &sd_cs_gpio; | ||||
| 
 | ||||
|     // TODO: SPI manager
 | ||||
|     api_hal_spi_lock(sd_fast_spi.spi); | ||||
| 
 | ||||
|     // configure pin as input
 | ||||
|     gpio_init_ex(sd_cs_record, GpioModeInput, GpioPullUp, GpioSpeedVeryHigh); | ||||
|     delay(1); | ||||
| 
 | ||||
|     // if gpio_read == 0 return true else return false
 | ||||
|     result = !gpio_read(sd_cs_record); | ||||
| 
 | ||||
|     // configure pin back
 | ||||
|     gpio_init_ex(sd_cs_record, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); | ||||
|     gpio_write(sd_cs_record, 1); | ||||
|     delay(1); | ||||
| 
 | ||||
|     // TODO: SPI manager
 | ||||
|     api_hal_spi_unlock(sd_fast_spi.spi); | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| void enable_cc1101_irq() { | ||||
|     HAL_NVIC_SetPriority(EXTI4_IRQn, 5, 0); | ||||
|     HAL_NVIC_EnableIRQ(EXTI4_IRQn); | ||||
|  | ||||
| @ -68,8 +68,6 @@ static inline bool hal_gpio_read(const GpioPin* gpio) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool hal_gpio_read_sd_detect(void); | ||||
| 
 | ||||
| void enable_cc1101_irq(); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
|  | ||||
| @ -6,6 +6,7 @@ | ||||
| #include <stm32wbxx_ll_pwr.h> | ||||
| #include <stm32wbxx_ll_hsem.h> | ||||
| #include <stm32wbxx_ll_cortex.h> | ||||
| #include <stm32wbxx_ll_gpio.h> | ||||
| 
 | ||||
| #include <main.h> | ||||
| #include <hw_conf.h> | ||||
| @ -195,3 +196,11 @@ void api_hal_power_dump_state(string_t buffer) { | ||||
|         bq25896_get_ntc_mpct() | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| void api_hal_power_enable_external_3_3v(){ | ||||
|     LL_GPIO_SetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin); | ||||
| } | ||||
| 
 | ||||
| void api_hal_power_disable_external_3_3v(){ | ||||
|     LL_GPIO_ResetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin); | ||||
| } | ||||
| @ -25,7 +25,6 @@ const InputPin input_pins[] = { | ||||
| 
 | ||||
| const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin); | ||||
| 
 | ||||
| const GpioPin sd_cs_gpio = {SD_CS_GPIO_Port, SD_CS_Pin}; | ||||
| const GpioPin vibro_gpio = {VIBRO_GPIO_Port, VIBRO_Pin}; | ||||
| const GpioPin ibutton_gpio = {iBTN_GPIO_Port, iBTN_Pin}; | ||||
| const GpioPin cc1101_g0_gpio = {CC1101_G0_GPIO_Port, CC1101_G0_Pin}; | ||||
|  | ||||
| @ -53,7 +53,6 @@ typedef struct { | ||||
| extern const InputPin input_pins[]; | ||||
| extern const size_t input_pins_count; | ||||
| 
 | ||||
| extern const GpioPin sd_cs_gpio; | ||||
| extern const GpioPin vibro_gpio; | ||||
| extern const GpioPin ibutton_gpio; | ||||
| extern const GpioPin cc1101_g0_gpio; | ||||
|  | ||||
							
								
								
									
										22
									
								
								firmware/targets/f5/api-hal/api-hal-sd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								firmware/targets/f5/api-hal/api-hal-sd.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| #include "api-hal-sd.h" | ||||
| #include <stm32wbxx_ll_gpio.h> | ||||
| #include <furi.h> | ||||
| 
 | ||||
| void hal_sd_detect_init(void) { | ||||
|     // low speed input with pullup
 | ||||
|     LL_GPIO_SetPinMode(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_MODE_INPUT); | ||||
|     LL_GPIO_SetPinSpeed(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_SPEED_FREQ_LOW); | ||||
|     LL_GPIO_SetPinPull(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_PULL_UP); | ||||
| } | ||||
| 
 | ||||
| void hal_sd_detect_set_low(void) { | ||||
|     // low speed input with pullup
 | ||||
|     LL_GPIO_SetPinMode(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_MODE_OUTPUT); | ||||
|     LL_GPIO_SetPinOutputType(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_OUTPUT_OPENDRAIN); | ||||
|     LL_GPIO_ResetOutputPin(SD_CD_GPIO_Port, SD_CD_Pin); | ||||
| } | ||||
| 
 | ||||
| bool hal_sd_detect(void) { | ||||
|     bool result = !(LL_GPIO_IsInputPinSet(SD_CD_GPIO_Port, SD_CD_Pin)); | ||||
|     return result; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 SG
						SG