From 27ae2a8fa9d62be61eeb097f956b43a2e78b1080 Mon Sep 17 00:00:00 2001 From: DrZlo13 Date: Wed, 18 Nov 2020 16:01:25 +0300 Subject: [PATCH] #FL-303 fix for some spi bugs, test app for sd-nfc interconnection (#247) * sd-nfc test app * do not hold spi in disable mode * disable pullups in nfc chip --- applications/applications.h | 18 +- applications/applications.mk | 12 +- applications/sd-nfc/sdnfc.cpp | 164 ++++++++++++++++++ firmware/targets/f3/Src/spi.c | 40 +++-- .../source/st25r3916/rfal_rfst25r3916.c | 7 + 5 files changed, 225 insertions(+), 16 deletions(-) create mode 100644 applications/sd-nfc/sdnfc.cpp diff --git a/applications/applications.h b/applications/applications.h index 1efbc57d..1cdfde3e 100644 --- a/applications/applications.h +++ b/applications/applications.h @@ -38,6 +38,7 @@ void app_gpio_test(void* p); void app_ibutton(void* p); void cli_task(void* p); void music_player(void* p); +void sdnfc(void* p); void floopper_bloopper(void* p); const FlipperStartupApp FLIPPER_STARTUP[] = { @@ -185,7 +186,14 @@ const FlipperStartupApp FLIPPER_STARTUP[] = { #endif #ifdef APP_FLOOPPER_BLOOPPER - {.app = floopper_bloopper, .name = "Floopper Bloopper", .libs = {1, FURI_LIB{"gui_task"}}}, + {.app = floopper_bloopper, + .name = "Floopper Bloopper", + .libs = {1, FURI_LIB{"gui_task"}}, + .icon = A_Games_14}, +#endif + +#ifdef APP_SDNFC + {.app = sdnfc, .name = "sdnfc", .libs = {1, FURI_LIB{"gui_task"}}, .icon = A_Plugins_14}, #endif }; @@ -265,7 +273,13 @@ const FlipperStartupApp FLIPPER_PLUGINS[] = { #endif #ifdef BUILD_FLOOPPER_BLOOPPER - {.app = floopper_bloopper, .name = "Floopper Bloopper", .libs = {1, FURI_LIB{"gui_task"}}}, + {.app = floopper_bloopper, + .name = "Floopper Bloopper", + .libs = {1, FURI_LIB{"gui_task"}}, + .icon = A_Games_14}, #endif +#ifdef BUILD_SDNFC + {.app = sdnfc, .name = "sdnfc", .libs = {1, FURI_LIB{"gui_task"}}, .icon = A_Plugins_14}, +#endif }; \ No newline at end of file diff --git a/applications/applications.mk b/applications/applications.mk index c8440e94..acfb09c1 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -279,9 +279,19 @@ endif BUILD_IBUTTON ?= 0 ifeq ($(BUILD_IBUTTON), 1) CFLAGS += -DBUILD_IBUTTON -CPP_SOURCES += $(wildcard $(APP_DIR)/ibutton/ibutton.cpp) +CPP_SOURCES += $(APP_DIR)/ibutton/ibutton.cpp endif +APP_SDNFC ?= 0 +ifeq ($(APP_SDNFC), 1) +CFLAGS += -DAPP_SDNFC +BUILD_SDNFC = 1 +endif +BUILD_SDNFC ?= 0 +ifeq ($(BUILD_SDNFC), 1) +CFLAGS += -DBUILD_SDNFC +CPP_SOURCES += $(APP_DIR)/sdnfc/sdnfc.cpp +endif # device drivers APP_GUI ?= 0 diff --git a/applications/sd-nfc/sdnfc.cpp b/applications/sd-nfc/sdnfc.cpp new file mode 100644 index 00000000..b8a2ad3c --- /dev/null +++ b/applications/sd-nfc/sdnfc.cpp @@ -0,0 +1,164 @@ +#include "app-template.h" + +extern "C" { +#include +#include +#include +#include +#include +#include +} + +#include "fatfs/ff.h" +#include "stm32_adafruit_sd.h" + +// event enumeration type +typedef uint8_t event_t; + +// app state class +class AppSdNFCState { +public: + // state data + const char* name; + + // state initializer + AppSdNFCState() { + name = "sd nfc test"; + } +}; + +// app events class +class AppSdNFCEvent { +public: + // events enum + static const event_t EventTypeTick = 0; + static const event_t EventTypeKey = 1; + + // payload + union { + InputEvent input; + } value; + + // event type + event_t type; +}; + +// our app derived from base AppTemplate class +// with template variables +class AppSdNFC : public AppTemplate { +public: + GpioPin* red_led_record; + GpioPin* green_led_record; + + void run(); + void render(CanvasApi* canvas); + void set_error(const char* text); + void set_text(const char* text); + void light_red(); + void light_green(); + void blink_red(); + void blink_green(); +}; + +FATFS sd_fat_fs; +char sd_path[6] = ""; + +// start app +void AppSdNFC::run() { + // create pin + GpioPin red_led = led_gpio[0]; + GpioPin green_led = led_gpio[1]; + + // TODO open record + red_led_record = &red_led; + green_led_record = &green_led; + + // configure pin + gpio_init(red_led_record, GpioModeOutputOpenDrain); + gpio_init(green_led_record, GpioModeOutputOpenDrain); + + uint8_t rfal_result = rfalNfcInitialize(); + if(rfal_result) { + set_text("rfal init fail"); + blink_red(); + } + + uint8_t bsp_result = BSP_SD_Init(); + if(bsp_result) { + set_error("sd init fail"); + } + + FRESULT result; + + result = f_mount(&sd_fat_fs, sd_path, 1); + if(result) { + set_error("sd mount fail"); + } + + light_green(); + set_text("all good"); + + AppSdNFCEvent event; + while(1) { + if(get_event(&event, 1000)) { + if(event.type == AppSdNFCEvent::EventTypeKey) { + // press events + if(event.value.input.state && event.value.input.input == InputBack) { + exit(); + } + } + } + + // signal to force gui update + update_gui(); + }; +} + +// render app +void AppSdNFC::render(CanvasApi* canvas) { + canvas->set_color(canvas, ColorBlack); + canvas->set_font(canvas, FontPrimary); + canvas->draw_str(canvas, 2, 12, state.name); +} + +void AppSdNFC::set_error(const char* text) { + light_red(); + set_text(text); + update_gui(); + while(1) + ; +} + +void AppSdNFC::set_text(const char* text) { + acquire_state(); + state.name = text; + release_state(); +} + +void AppSdNFC::light_red() { + gpio_write(red_led_record, false); +} + +void AppSdNFC::light_green() { + gpio_write(green_led_record, false); +} + +void AppSdNFC::blink_red() { + gpio_write(red_led_record, false); + delay(500); + gpio_write(red_led_record, true); + delay(500); +} + +void AppSdNFC::blink_green() { + gpio_write(green_led_record, false); + delay(500); + gpio_write(green_led_record, true); + delay(500); +} + +// app enter function +extern "C" void sdnfc(void* p) { + AppSdNFC* app = new AppSdNFC(); + app->run(); +} \ No newline at end of file diff --git a/firmware/targets/f3/Src/spi.c b/firmware/targets/f3/Src/spi.c index 5eff3b00..07d1aa3a 100644 --- a/firmware/targets/f3/Src/spi.c +++ b/firmware/targets/f3/Src/spi.c @@ -19,9 +19,10 @@ /* Includes ------------------------------------------------------------------*/ #include "spi.h" +#include "cmsis_os.h" /* USER CODE BEGIN 0 */ - +void Enable_SPI(SPI_HandleTypeDef* spi); /* USER CODE END 0 */ SPI_HandleTypeDef hspi1; @@ -190,9 +191,7 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle) /* USER CODE BEGIN 1 */ void NFC_SPI_Reconfigure() { - if (HAL_SPI_DeInit(&SPI_R) != HAL_OK) { - Error_Handler(); - } + osKernelLock(); SPI_R.Init.Mode = SPI_MODE_MASTER; SPI_R.Init.Direction = SPI_DIRECTION_2LINES; @@ -211,12 +210,14 @@ void NFC_SPI_Reconfigure() { if (HAL_SPI_Init(&SPI_R) != HAL_OK) { Error_Handler(); } + + Enable_SPI(&SPI_R); + + osKernelUnlock(); } void SD_SPI_Reconfigure_Slow(void) { - if (HAL_SPI_DeInit(&SPI_SD_HANDLE) != HAL_OK) { - Error_Handler(); - } + osKernelLock(); SPI_SD_HANDLE.Init.Mode = SPI_MODE_MASTER; SPI_SD_HANDLE.Init.Direction = SPI_DIRECTION_2LINES; @@ -235,12 +236,14 @@ void SD_SPI_Reconfigure_Slow(void) { if(HAL_SPI_Init(&SPI_SD_HANDLE) != HAL_OK) { Error_Handler(); } + + Enable_SPI(&SPI_SD_HANDLE); + + osKernelUnlock(); } void SD_SPI_Reconfigure_Fast(void) { - if(HAL_SPI_DeInit(&SPI_SD_HANDLE) != HAL_OK) { - Error_Handler(); - } + osKernelLock(); SPI_SD_HANDLE.Init.Mode = SPI_MODE_MASTER; SPI_SD_HANDLE.Init.Direction = SPI_DIRECTION_2LINES; @@ -259,12 +262,14 @@ void SD_SPI_Reconfigure_Fast(void) { if(HAL_SPI_Init(&SPI_SD_HANDLE) != HAL_OK) { Error_Handler(); } + + Enable_SPI(&SPI_SD_HANDLE); + + osKernelUnlock(); } void CC1101_SPI_Reconfigure(void) { - if(HAL_SPI_DeInit(&SPI_R) != HAL_OK) { - Error_Handler(); - } + osKernelLock(); SPI_R.Init.Mode = SPI_MODE_MASTER; SPI_R.Init.Direction = SPI_DIRECTION_2LINES; @@ -283,8 +288,17 @@ void CC1101_SPI_Reconfigure(void) { if(HAL_SPI_Init(&SPI_R) != HAL_OK) { Error_Handler(); } + + Enable_SPI(&SPI_R); + + osKernelUnlock(); } +void Enable_SPI(SPI_HandleTypeDef* spi_instance){ + if((spi_instance->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) { + __HAL_SPI_ENABLE(spi_instance); + } +} /* USER CODE END 1 */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib/ST25RFAL002/source/st25r3916/rfal_rfst25r3916.c b/lib/ST25RFAL002/source/st25r3916/rfal_rfst25r3916.c index a2ddb280..55c6deb6 100755 --- a/lib/ST25RFAL002/source/st25r3916/rfal_rfst25r3916.c +++ b/lib/ST25RFAL002/source/st25r3916/rfal_rfst25r3916.c @@ -467,6 +467,13 @@ ReturnCode rfalInitialize( void ) /* Apply RF Chip generic initialization */ rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_INIT) ); + // TODO: + // I don't want to mess with config table ("Default Analog Configuration for Chip-Specific Reset", rfal_analogConfigTbl.h) + // so with every rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_CHIP_INIT)) currently we need to clear pulldown bits + // luckily for us this is done only here + + // disable pulldowns + st25r3916ClrRegisterBits(ST25R3916_REG_IO_CONF2, ( ST25R3916_REG_IO_CONF2_miso_pd1 | ST25R3916_REG_IO_CONF2_miso_pd2 ) ); /*******************************************************************************/ /* Enable External Field Detector as: Automatics */