diff --git a/.config b/.config
index a8f14f1..aca33a5 100644
--- a/.config
+++ b/.config
@@ -213,14 +213,14 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
CONFIG_RT_USING_POSIX_FS=y
CONFIG_RT_USING_POSIX_DEVIO=y
# CONFIG_RT_USING_POSIX_STDIO is not set
-# CONFIG_RT_USING_POSIX_POLL is not set
+CONFIG_RT_USING_POSIX_POLL=y
# CONFIG_RT_USING_POSIX_SELECT is not set
# CONFIG_RT_USING_POSIX_SOCKET is not set
# CONFIG_RT_USING_POSIX_TERMIOS is not set
# CONFIG_RT_USING_POSIX_AIO is not set
# CONFIG_RT_USING_POSIX_MMAN is not set
-# CONFIG_RT_USING_POSIX_DELAY is not set
-# CONFIG_RT_USING_POSIX_CLOCK is not set
+CONFIG_RT_USING_POSIX_DELAY=y
+CONFIG_RT_USING_POSIX_CLOCK=y
# CONFIG_RT_USING_POSIX_TIMER is not set
# CONFIG_RT_USING_PTHREADS is not set
# CONFIG_RT_USING_MODULE is not set
@@ -228,9 +228,10 @@ CONFIG_RT_USING_POSIX_DEVIO=y
#
# Interprocess Communication (IPC)
#
-# CONFIG_RT_USING_POSIX_PIPE is not set
-# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set
-# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set
+CONFIG_RT_USING_POSIX_PIPE=y
+CONFIG_RT_USING_POSIX_PIPE_SIZE=512
+CONFIG_RT_USING_POSIX_MESSAGE_QUEUE=y
+CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE=y
#
# Socket is in the 'Network' category
@@ -238,7 +239,8 @@ CONFIG_RT_USING_POSIX_DEVIO=y
# end of Interprocess Communication (IPC)
# end of POSIX (Portable Operating System Interface) layer
-# CONFIG_RT_USING_CPLUSPLUS is not set
+CONFIG_RT_USING_CPLUSPLUS=y
+# CONFIG_RT_USING_CPLUSPLUS11 is not set
# end of C/C++ and POSIX layer
#
@@ -633,13 +635,7 @@ CONFIG_PKG_USING_SQLITE_V3193=y
# CONFIG_PKG_USING_FLASH_BLOB is not set
# CONFIG_PKG_USING_MLIBC is not set
# CONFIG_PKG_USING_TASK_MSG_BUS is not set
-CONFIG_PKG_USING_UART_FRAMEWORK=y
-CONFIG_PKG_UART_FRAMEWORK_PATH="/packages/system/UartFramework"
-# CONFIG_PKG_USING_UART_FRAMEWORK_V001 is not set
-# CONFIG_PKG_USING_UART_FRAMEWORK_V004 is not set
-# CONFIG_PKG_USING_UART_FRAMEWORK_V100 is not set
-CONFIG_PKG_USING_UART_FRAMEWORK_LATEST_VERSION=y
-CONFIG_PKG_UART_FRAMEWORK_VER="latest"
+# CONFIG_PKG_USING_UART_FRAMEWORK is not set
# CONFIG_PKG_USING_SFDB is not set
# CONFIG_PKG_USING_RTP is not set
# CONFIG_PKG_USING_REB is not set
@@ -858,6 +854,7 @@ CONFIG_PKG_UART_FRAMEWORK_VER="latest"
# CONFIG_PKG_USING_MLX90393 is not set
# CONFIG_PKG_USING_MLX90392 is not set
# CONFIG_PKG_USING_MLX90394 is not set
+# CONFIG_PKG_USING_MLX90396 is not set
# CONFIG_PKG_USING_MLX90397 is not set
# CONFIG_PKG_USING_MS5611 is not set
# CONFIG_PKG_USING_MAX31865 is not set
diff --git a/.cproject b/.cproject
index df1c29d..f6d6888 100644
--- a/.cproject
+++ b/.cproject
@@ -95,6 +95,8 @@
+
+
@@ -143,396 +145,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -597,6 +213,8 @@
+
+
@@ -687,6 +305,8 @@
+
+
@@ -696,7 +316,9 @@
-
+
+
+
@@ -781,6 +403,8 @@
+
+
@@ -790,7 +414,9 @@
-
+
+
+
@@ -873,6 +499,8 @@
+
+
@@ -882,7 +510,9 @@
-
+
+
+
@@ -892,7 +522,7 @@
-
+
diff --git a/.project b/.project
index ece7f83..8dbbf21 100644
--- a/.project
+++ b/.project
@@ -20,6 +20,7 @@
org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.core.ccnature
org.rt-thread.studio.rttnature
org.eclipse.cdt.managedbuilder.core.managedBuildNature
org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
diff --git a/.settings/.rtmenus b/.settings/.rtmenus
index c35ae97..f420cad 100644
Binary files a/.settings/.rtmenus and b/.settings/.rtmenus differ
diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
index ec88f73..1aaff07 100644
--- a/.settings/language.settings.xml
+++ b/.settings/language.settings.xml
@@ -5,7 +5,7 @@
-
+
diff --git a/applications/DATA/DATA_comm.c b/applications/DATA/DATA_comm.c
index e75c88b..17827a8 100644
--- a/applications/DATA/DATA_comm.c
+++ b/applications/DATA/DATA_comm.c
@@ -23,6 +23,9 @@ rt_mq_t proc_mq;
char cjson_falg=0;//是否解析cjson
char *json_buffer=NULL;
+
+//
+
/**
* 截取两个指定子串之间的内容
* @param src 源字符串
@@ -117,58 +120,63 @@ void pasre_DAT(const char *api, const char *json_str)
}
else if (strcmp(api, "SC810") == 0)
{
- char STime[25];
- char pTime[10];
+ char Work_[25];
+ char Dye_[25];
+ char STime_[25];
+ char pTime_[10];
// 字符串赋值
- GET_STRING(Work, root, "Work", sizeof(Work));
- GET_STRING(Dye, root, "Dye", sizeof(Dye));
- GET_STRING(STime, root, "STime", sizeof(STime));
- GET_STRING(pTime, root, "Time", sizeof(pTime));
+ GET_STRING(Work_, root, "Work", sizeof(Work_));
+ GET_STRING(Dye_, root, "Dye", sizeof(Dye_));
+ GET_STRING(STime_, root, "STime", sizeof(STime_));
+ GET_STRING(pTime_, root, "Time", sizeof(pTime_));
// 定义足够大的缓冲区
char sql[512] = {0}; // 初始化为 0
// 安全格式化
rt_snprintf(sql, sizeof(sql),
- "INSERT INTO WorkorderSteps(WorkOrder,DYELOT,ReDye,StartTime,Time)"
- "VALUES('%s','%s',0,%s,%s,)",
- Work, Dye, STime,pTime);
+ "INSERT INTO WorkOrder(WorkOrder,DYELOT,ReDye,StartTime,Time)"
+ "VALUES('%s','%s',0,'%s','%s')",
+ Work_, Dye_, STime_,pTime_);
if( db_send_command(DB_CMD_EXEC, sql, 500)==RT_EOK) //
{
- cJSON_AddItemToObject(dat,"Work",cJSON_CreateString(Work));
- cJSON_AddItemToObject(dat,"ReDye",cJSON_CreateNumber(Redye));
+ cJSON_AddItemToObject(dat,"Work",cJSON_CreateString(Work_));
+ cJSON_AddItemToObject(dat,"ReDye",cJSON_CreateNumber(0));
}
}
else if (strcmp(api, "SC811") == 0)
{//工单明细
+ char Work_[25];
+ char Dye_[25];
+ char StepID_[4];
+ char SIDS1_[4];
+ int StepN_;
+ int P1_;
+ int P2_;
+ int P3_;
+ int P4_;
+ int P5_;
+ int P1S1_;
+ int P2S1_;
+ int P3S1_;
+ int P4S1_;
+ int P5S1_;
// 字符串赋值
- GET_STRING(Work, root, "Work", sizeof(Work));
- GET_STRING(Dye, root, "Dye", sizeof(Dye));
- GET_STRING(StepID, root, "StepID", sizeof(StepID));
- GET_STRING(SIDS1, root, "SIDS1", sizeof(SIDS1));
- //GET_STRING(SIDS2, root, "SIDS2", sizeof(SIDS2));
- //GET_STRING(SIDS3, root, "SIDS3", sizeof(SIDS3));
+ GET_STRING(Work_, root, "Work", sizeof(Work_));
+ GET_STRING(Dye_, root, "Dye", sizeof(Dye_));
+ GET_STRING(StepID_, root, "StepID", sizeof(StepID_));
+ GET_STRING(SIDS1_, root, "SIDS1", sizeof(SIDS1_));
//整数
- GET_INT_FROM_ANY(StepN, root, "Step", 0);
- GET_INT_FROM_ANY(P1, root, "P1", 0);
- GET_INT_FROM_ANY(P2, root, "P2", 0);
- GET_INT_FROM_ANY(P3, root, "P3", 0);
- GET_INT_FROM_ANY(P4, root, "P4", 0);
- GET_INT_FROM_ANY(P5, root, "P5", 0);
- GET_INT_FROM_ANY(P1S1, root, "P1S1",0);
- GET_INT_FROM_ANY(P2S1, root, "P2S1",0);
- GET_INT_FROM_ANY(P3S1, root, "P3S1",0);
- GET_INT_FROM_ANY(P4S1, root, "P4S1",0);
- GET_INT_FROM_ANY(P5S1, root, "P5S1",0);
- //GET_INT_FROM_ANY(P1S2, root, "P1S2",0);
- //GET_INT_FROM_ANY(P2S2, root, "P2S2",0);
- //GET_INT_FROM_ANY(P3S2, root, "P3S2",0);
- //GET_INT_FROM_ANY(P4S2, root, "P4S2",0);
- //GET_INT_FROM_ANY(P5S2, root, "P5S2",0);
- //GET_INT_FROM_ANY(P1S3, root, "P1S3",0);
- //GET_INT_FROM_ANY(P2S3, root, "P2S3",0);
- //GET_INT_FROM_ANY(P3S3, root, "P3S3",0);
- //GET_INT_FROM_ANY(P4S3, root, "P4S3",0);
- //GET_INT_FROM_ANY(P5S3, root, "P5S3",0);
+ GET_INT_FROM_ANY(StepN_, root, "Step", 0);
+ GET_INT_FROM_ANY(P1_, root, "P1", 0);
+ GET_INT_FROM_ANY(P2_, root, "P2", 0);
+ GET_INT_FROM_ANY(P3_, root, "P3", 0);
+ GET_INT_FROM_ANY(P4_, root, "P4", 0);
+ GET_INT_FROM_ANY(P5_, root, "P5", 0);
+ GET_INT_FROM_ANY(P1S1_, root, "P1S1",0);
+ GET_INT_FROM_ANY(P2S1_, root, "P2S1",0);
+ GET_INT_FROM_ANY(P3S1_, root, "P3S1",0);
+ GET_INT_FROM_ANY(P4S1_, root, "P4S1",0);
+ GET_INT_FROM_ANY(P5S1_, root, "P5S1",0);
// 定义足够大的缓冲区
char sql[512] = {0}; // 初始化为 0
@@ -176,41 +184,124 @@ void pasre_DAT(const char *api, const char *json_str)
// 安全格式化
rt_snprintf(sql, sizeof(sql),
"INSERT INTO WorkorderSteps(WorkOrder,DYELOT,ReDye,Step,StepID,P1,P2,P3,P4,P5,StepID_S1,P1_S1,P2_S1,P3_S1,P4_S1,P5_S1)"
- "VALUES('%s','%s',0,%d,%s,%d,%d,%d,%d,%d,'%s',%d,%d,%d,%d,%d)",
- Work, Dye, StepN,StepID,P1, P2, P3, P4, P5,SIDS1,P1S1,P2S1,P3S1,P4S1,P5S1 );
+ "VALUES('%s','%s',0,%d,'%s',%d,%d,%d,%d,%d,'%s',%d,%d,%d,%d,%d)",
+ Work_, Dye_, StepN_,StepID_,P1_, P2_, P3_, P4_, P5_,SIDS1_,P1S1_,P2S1_,P3S1_,P4S1_,P5S1_ );
if( db_send_command(DB_CMD_EXEC, sql, 500)==RT_EOK) //
{
- cJSON_AddItemToObject(dat,"Work",cJSON_CreateString(Work));
- cJSON_AddItemToObject(dat,"ReDye",cJSON_CreateNumber(Redye));
- cJSON_AddItemToObject(dat,"Step",cJSON_CreateNumber(StepN));
+ cJSON_AddItemToObject(dat,"Work",cJSON_CreateString(Work_));
+ cJSON_AddItemToObject(dat,"ReDye",cJSON_CreateNumber(0));
+ cJSON_AddItemToObject(dat,"Step",cJSON_CreateNumber(StepN_));
}
}
- else if (strcmp(api, "SC812") == 0) {
- //工单设定
+ else if (strcmp(api, "SC812") == 0)
+ {//工单设定
+ char Work_[25];
+ int Pump_;
+ int Blower_;
+ int ClothWheel_;
+ int Swing_;
+ int Nozzle_;
+ // 字符串赋值
+ GET_STRING(Work_, root, "WorkOrder", sizeof(Work_));
+ //整数
+ GET_INT_FROM_ANY(Pump_, root, "PumpSpeed", 0);
+ GET_INT_FROM_ANY(Blower_, root, "Blower", 0);
+ GET_INT_FROM_ANY(ClothWheel_, root, "ClothWheel", 0);
+ GET_INT_FROM_ANY(Swing_, root, "Swing", 0);
+ GET_INT_FROM_ANY(Nozzle_, root, "Nozzle", 0);
+
+ // 定义足够大的缓冲区
+ char sql[512] = {0}; // 初始化为 0
+ // 安全格式化
+ rt_snprintf(sql, sizeof(sql),
+ "INSERT OR IGNORE INTO WorkOrderSet(WorkOrder,ReDye,PumpSpeed,Blower,ClothWheel,Swing,Nozzle)"
+ "VALUES('%s',0,%d,%d,%d,%d,%d)",
+ Work_, Pump_,Blower_,ClothWheel_, Swing_, Nozzle_);
+ if( db_send_command(DB_CMD_EXEC, sql, 500)==RT_EOK) //
+ {
+ cJSON_AddItemToObject(dat,"Work",cJSON_CreateString(Work_));
+ cJSON_AddItemToObject(dat,"ReDye",cJSON_CreateNumber(0));
+ }
}
- else if (strcmp(api, "SC813") == 0) {
- printf("Processing:SC813\n");
+ else if (strcmp(api, "SC813") == 0)
+ {//领料单插入
+ char Work_[25];
+ char Dye_[25];
+ char ProductCode_[15];
+ char ProductName_[15];
+ char Grams_[8];
+ int ProductType_;
+ int StepN_;
+ //字符
+ GET_STRING(Work_, root, "Work", sizeof(Work_));
+ GET_STRING(Dye_, root, "Dye", sizeof(Dye_));
+ GET_STRING(ProductName_, root, "ProductName", sizeof(ProductName_));
+ GET_STRING(ProductCode_, root, "ProductCode", sizeof(ProductCode_));
+ GET_STRING(Grams_, root, "Grams", sizeof(Grams_));
+ //整数
+ GET_INT_FROM_ANY(StepN_, root, "Step", 0);
+ GET_INT_FROM_ANY(ProductType_, root, "ProductType", 0);
+
+ // 定义足够大的缓冲区
+ char sql[512] = {0}; // 初始化为 0
+ // 安全格式化
+ rt_snprintf(sql, sizeof(sql),
+ "INSERT OR IGNORE INTO Dyelot(WorkOrder,Dyelot,ReDye,Step,ProductCode,ProductName,ProductType,Grams)"
+ "VALUES('%s','%s',0,%d,%s,%s,%d,%s)",
+ Work_, Dye_,StepN_,ProductCode_,ProductName_ ,ProductType_,Grams_);
+ if( db_send_command(DB_CMD_EXEC, sql, 500)==RT_EOK) //
+ {
+ cJSON_AddItemToObject(dat,"Work",cJSON_CreateString(Work_));
+ cJSON_AddItemToObject(dat,"Dye",cJSON_CreateString(Dye_));
+ cJSON_AddItemToObject(dat,"ReDye",cJSON_CreateNumber(0));
+ cJSON_AddItemToObject(dat,"Step",cJSON_CreateNumber(StepN_));
+ }
}
- else if (strcmp(api, "SC820") == 0) {
- printf("Processing:SC820\n");
+ else if (strcmp(api, "SC820") == 0)
+ {//设置系统时间
+ char Time_[25];
+
+ GET_STRING(Time_, root, "Work", sizeof(Time_));
+
+ cJSON_AddItemToObject(dat,"time",cJSON_CreateString("systime"));
}
- else if (strcmp(api, "SC821") == 0) {
+ else if (strcmp(api, "SC821") == 0)
+ {
printf("Processing:SC821\n");
}
- else if (strcmp(api, "SC822") == 0) {
+ else if (strcmp(api, "SC822") == 0)
+ {
printf("Processing:SC822\n");
}
- else if (strcmp(api, "SC827") == 0) {
+ else if (strcmp(api, "SC827") == 0)
+ {
printf("Processing:SC827\n");
}
- else if (strcmp(api, "SC828") == 0) {
+ else if (strcmp(api, "SC828") == 0)
+ {
printf("Processing:SC828\n");
}
- else if (strcmp(api, "SC829") == 0) {
- printf("Processing:SC829\n");
+ else if (strcmp(api, "SC829") == 0)
+ {//锁定自动
+ char NAME_[4];
+ char VALUE_[4];
+ GET_STRING(NAME_, root, "NAME", sizeof(NAME_));
+ GET_STRING(VALUE_, root, "VALUE", sizeof(VALUE_));
+
+ if (strcmp(NAME_, "LOCK") == 0) {
+ if (strcmp(VALUE_, "True") == 0)
+ {MACHINE_LOCK=1;}else{MACHINE_LOCK=0;}
+ }
+ if (strcmp(NAME_, "AUTO") == 0) {
+ if (strcmp(VALUE_, "True") == 0)
+ {MACHINE_AUTO=1;}else{MACHINE_AUTO=0;}
+ }
+
+ cJSON_AddItemToObject(dat,"NAME",cJSON_CreateString(NAME_));
+ cJSON_AddItemToObject(dat,"VALUE",cJSON_CreateString(VALUE_));
}
- else if (strcmp(api, "SC830") == 0) {
- //当前信息
+ else if (strcmp(api, "SC830") == 0)
+ {//当前信息
cJSON_AddItemToObject(dat,"ERR",cJSON_CreateBool(MACHINE_ERR));
cJSON_AddItemToObject(dat,"LOCK",cJSON_CreateBool(MACHINE_LOCK));
cJSON_AddItemToObject(dat,"Status",cJSON_CreateString(Message));
@@ -382,7 +473,7 @@ int data_comm_init(void)
}
rt_thread_t tid = rt_thread_create("data_comm", proc_thread_entry, RT_NULL,
- 1024*4, 20, 10);
+ 1024*6, 20, 10);
if (tid != RT_NULL)
{
rt_thread_startup(tid);
diff --git a/applications/DATA/DATA_uart.c b/applications/DATA/DATA_uart.c
index 47d5566..afb06a4 100644
--- a/applications/DATA/DATA_uart.c
+++ b/applications/DATA/DATA_uart.c
@@ -133,15 +133,42 @@ static rt_err_t uart_rx_ind(rt_device_t dev, rt_size_t size)
return RT_EOK;
}
-// 从环形缓冲区提取一行
+// 从环形缓冲区提取一行rt_kprintf("%s\n",buf);
static int get_line(char *buf, int maxlen)
{
- int len = rt_ringbuffer_get(&rx_rb, (rt_uint8_t*)buf, maxlen - 1);
- if (len > 0) {
- buf[len] = '\0';
- return len;
- }
- return 0;
+ int len = 0;
+ rt_uint8_t ch;
+
+ // 逐字节读取,直到遇到 '\n' 或缓冲区满
+ while (len < maxlen - 1)
+ {
+ // 从环形缓冲区读一个字节
+ if (rt_ringbuffer_getchar(&rx_rb, &ch) == 0)
+ {
+ // 缓冲区为空,无数据可读
+ break;
+ }
+
+ buf[len++] = ch;
+
+ // 检查是否为行结束符
+ if (ch == '\n')
+ {
+ buf[len] = '\0'; // 添加字符串结束符
+ return len; // 返回完整行长度
+ }
+ }
+
+ // 如果没有遇到 '\n',说明不是完整的一行
+ // 我们可以选择:把已读的数据放回 ringbuffer,或丢弃(推荐放回)
+ // 这里选择:把所有读取的字符重新放回 ringbuffer
+ if (len > 0)
+ {
+ // 将已读取但未构成完整行的数据放回 ringbuffer 开头
+ rt_ringbuffer_put(&(rx_rb), (rt_uint8_t*)buf, len);
+ }
+
+ return 0; // 未收到完整行,返回 0
}
// 启动 UART 线程
diff --git a/applications/DATA/Variable.c b/applications/DATA/Variable.c
index 2716314..aaf4a6c 100644
--- a/applications/DATA/Variable.c
+++ b/applications/DATA/Variable.c
@@ -13,6 +13,7 @@ char machine_ID[3] = "23";
// 状态标志
char MACHINE_ERR = 0;
char MACHINE_LOCK = 0;
+char MACHINE_AUTO = 0;
char MACHINE_CALL = 0;
char MACHINE_USER = 0;
diff --git a/applications/DATA/Variable.h b/applications/DATA/Variable.h
index c11f5fd..ddbb2f9 100644
--- a/applications/DATA/Variable.h
+++ b/applications/DATA/Variable.h
@@ -13,6 +13,7 @@ extern char machine_ID[3];
// ===== 布尔变量 =====
extern char MACHINE_ERR;
extern char MACHINE_LOCK;
+extern char MACHINE_AUTO;
extern char MACHINE_CALL;
extern char MACHINE_USER;
diff --git a/applications/DBSQL/DB_SQLite.c b/applications/DBSQL/DB_SQLite.c
index aba6272..d9d73f5 100644
--- a/applications/DBSQL/DB_SQLite.c
+++ b/applications/DBSQL/DB_SQLite.c
@@ -17,7 +17,7 @@
#define DB_NAME "/SC828.db"
int db_HelperInit;
rt_mq_t db_mq = RT_NULL; //
-sqlite3 **db;
+sqlite3 *db;
// 消息队列对象与缓冲区(静态分配)
//static struct rt_mq db_mq;
@@ -45,7 +45,7 @@ static const char *sql_upgrade_workorder_set =
"CREATE TABLE WorkOrderSet (WorkOrder VARCHAR,ReDye INT DEFAULT (0),PumpSpeed INT,Blower INT,Swing INT,ClothWheel INT,Nozzle INT); ";
static const char *sql_upgrade_workorder =
- "CREATE TABLE WorkOrder (WorkOrder VARCHAR,Dyelot VARCHAR,ReDyeINT DEFAULT (0),ProgramNameVARCHAR,StartTime DATETIME,EndTime DATETIME,"
+ "CREATE TABLE WorkOrder (WorkOrder VARCHAR,Dyelot VARCHAR,ReDye INT DEFAULT (0),ProgramName VARCHAR,StartTime DATETIME,EndTime DATETIME,"
"Time TEXT,lock INT,State INT,ProgramID VARCHAR,Machines VARCHAR,color VARCHAR,ColorNumber VARCHAR,Client VARCHAR,ClothWeight VARCHAR,"
"ClothSpecies VARCHAR,BathRatio VARCHAR,Total VARCHAR,USER VARCHAR,ColorName VARCHAR,Remark TEXT); ";
@@ -183,54 +183,67 @@ void close_db_immediately(void) {
void db_sqlite_init_full(void)
{
if (access(DB_NAME, F_OK) == 0)
+ {//打开文件
+ if (sqlite3_open(DB_NAME, &db) == 0)
{
- rt_kprintf("DB open\n");
- if (db_connect(DB_NAME) == RT_EOK){
- if(db_table_is_exist("WorkorderSteps")<=0){
- if(db_create_database(sql_upgrade_workorder_steps)==0)
- {rt_kprintf("WorkorderSteps Created successfully \n");}else{rt_kprintf("WorkorderSteps Creation failed \n");}
- }
- if(db_table_is_exist("WorkOrderSet")<=0){
- if(db_create_database(sql_upgrade_workorder_set)==0)
- {rt_kprintf("WorkOrderSet Created successfully \n");}else{rt_kprintf("WorkOrderSet Creation failed \n");}
- }
- if(db_table_is_exist("WorkOrder")<=0){
- if(db_create_database(sql_upgrade_workorder)==0)
- {rt_kprintf("WorkOrder Created successfully \n");}else{rt_kprintf("WorkOrder Creation failed \n");}
- }
- if(db_table_is_exist("RUN")<=0){
- if(db_create_database(sql_upgrade_run_table)==0)
- {rt_kprintf("RUN Created successfully \n");}else{rt_kprintf("RUN Creation failed \n");}
- }
- if(db_table_is_exist("Dyelot")<=0){
- if(db_create_database(sql_upgrade_dyelot_table)==0)
- {rt_kprintf("Dyelot Created successfully \n");}else{rt_kprintf("Dyelot Creation failed \n");}
- }
- if(db_table_is_exist("IOLog")<=0){
- if(db_create_database(sql_upgrade_iolog_table)==0)
- {rt_kprintf("IOLog Created successfully \n");}else{rt_kprintf("IOLog Creation failed \n");}
- }
- if(db_table_is_exist("Chart")<=0){
- if(db_create_database(sql_upgrade_chart_table)==0)
- {rt_kprintf("Chart Created successfully \n");}else{rt_kprintf("Chart Creation failed \n");}
- }
- }else{
- rt_kprintf("DB ok\n");
- db_connect(DB_NAME);
+ rt_kprintf("[DataBASE]DB open\n");
+ //检查表格
+ if(db_table_is_exist("WorkorderSteps")==0){
+ rt_kprintf("[DataBASE]WorkorderSteps not exist \n");
+ if(sqlite3_exec(db,sql_upgrade_workorder_steps, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]WorkorderSteps Created successfully \n");}else{rt_kprintf("[DataBASE]WorkorderSteps Creation failed \n");}
+ }
+ if(db_table_is_exist("WorkOrderSet")==0){
+ rt_kprintf("[DataBASE]WorkOrderSet not exist \n");
+ if(sqlite3_exec(db,sql_upgrade_workorder_set, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]WorkOrderSet Created successfully \n");}else{rt_kprintf("[DataBASE]WorkOrderSet Creation failed \n");}
+ }
+ if(db_table_is_exist("WorkOrder")==0){
+ rt_kprintf("[DataBASE]WorkOrder not exist \n");
+ if(sqlite3_exec(db,sql_upgrade_workorder, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]WorkOrder Created successfully \n");}else{rt_kprintf("[DataBASE]WorkOrder Creation failed \n");}
+ }
+ if(db_table_is_exist("RUN")==0){
+ rt_kprintf("[DataBASE]RUN not exist \n");
+ if(sqlite3_exec(db,sql_upgrade_run_table, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]RUN Created successfully \n");}else{rt_kprintf("[DataBASE]RUN Creation failed \n");}
+ }
+ if(db_table_is_exist("Dyelot")==0){
+ rt_kprintf("[DataBASE]Dyelot not exist \n");
+ if(sqlite3_exec(db,sql_upgrade_dyelot_table, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]Dyelot Created successfully \n");}else{rt_kprintf("[DataBASE]Dyelot Creation failed \n");}
+ }
+ if(db_table_is_exist("IOLog")==0){
+ rt_kprintf("[DataBASE]IOLog not exist \n");
+ if(sqlite3_exec(db,sql_upgrade_iolog_table, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]IOLog Created successfully \n");}else{rt_kprintf("[DataBASE]IOLog Creation failed \n");}
+ }
+ if(db_table_is_exist("Chart")==0){
+ rt_kprintf("[DataBASE]Chart not exist \n");
+ if(sqlite3_exec(db,sql_upgrade_chart_table, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]Chart Created successfully \n");}else{rt_kprintf("[DataBASE]Chart Creation failed \n");}
}
-
}else{
- rt_kprintf("DB open failed \n");
- sqlite3_open(DB_NAME, db);
- //创建表
- db_create_database(sql_upgrade_workorder_steps);
- db_create_database(sql_upgrade_workorder_set);
- db_create_database(sql_upgrade_workorder);
- db_create_database(sql_upgrade_run_table);
- db_create_database(sql_upgrade_dyelot_table);
- db_create_database(sql_upgrade_iolog_table);
- db_create_database(sql_upgrade_chart_table);
+ rt_kprintf("[DataBASE]DB not open\n");
}
+ }else{
+ rt_kprintf("DB open failed \n");
+ sqlite3_open(DB_NAME, &db);
+ if(sqlite3_exec(db,sql_upgrade_workorder_steps, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]WorkorderSteps Created successfully \n");}else{rt_kprintf("[DataBASE]WorkorderSteps Creation failed \n");}
+ if(sqlite3_exec(db,sql_upgrade_workorder_set, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]WorkOrderSet Created successfully \n");}else{rt_kprintf("[DataBASE]WorkOrderSet Creation failed \n");}
+ if(sqlite3_exec(db,sql_upgrade_workorder, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]WorkOrder Created successfully \n");}else{rt_kprintf("[DataBASE]WorkOrder Creation failed \n");}
+ if(sqlite3_exec(db,sql_upgrade_run_table, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]RUN Created successfully \n");}else{rt_kprintf("[DataBASE]RUN Creation failed \n");}
+ if(sqlite3_exec(db,sql_upgrade_dyelot_table, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]Dyelot Created successfully \n");}else{rt_kprintf("[DataBASE]Dyelot Creation failed \n");}
+ if(sqlite3_exec(db,sql_upgrade_iolog_table, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]IOLog Created successfully \n");}else{rt_kprintf("[DataBASE]IOLog Creation failed \n");}
+ if(sqlite3_exec(db,sql_upgrade_chart_table, 0, 0, 0)==0)
+ {rt_kprintf("[DataBASE]Chart Created successfully \n");}else{rt_kprintf("[DataBASE]Chart Creation failed \n");}
+ }
}
/**
diff --git a/applications/LVGL/lv_port_disp.c b/applications/LVGL/lv_port_disp.c
new file mode 100644
index 0000000..0e72892
--- /dev/null
+++ b/applications/LVGL/lv_port_disp.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2025-10-27 Administrator the first version
+ */
+
+#include "lvgl.h"
+#include "lv_port_disp.h"
+#include "ssd1963.h"
+
+// 屏幕分辨率(请根据实际 LCD 调整)
+#define LCD_WIDTH 480
+#define LCD_HEIGHT 272
+
+// 绘图缓冲区:建议为屏幕宽度 * 10 行
+static lv_color_t draw_buf1[LCD_WIDTH * 10]; // 前缓冲
+static lv_color_t draw_buf2[LCD_WIDTH * 10]; // 后缓冲(可选,用于双缓冲)
+
+// LVGL 绘图缓冲区描述符
+static lv_disp_draw_buf_t draw_buf;
+
+// 刷屏完成回调
+static void disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
+{
+ // 设置 SSD1963 显示窗口
+ ssd1963_set_window(area->x1, area->y1, area->x2, area->y2);
+
+ // 写入像素数据
+ uint32_t size = (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1);
+ for (uint32_t i = 0; i < size; i++) {
+ SSD1963_DATA_ADDR = color_p[i].full; // 使用 FSMC 写入
+ }
+
+ // ✅ 必须调用!通知 LVGL 刷屏已完成
+ lv_disp_flush_ready(disp_drv);
+}
+
+/**
+ * @brief 初始化 LVGL 显示驱动
+ */
+void lv_port_disp_init(void)
+{
+ // 1. 初始化 FSMC 总线(由 STM32CubeMX 生成)
+ // MX_FSMC_Init();
+
+ // 2. 初始化 SSD1963 控制器
+ ssd1963_init(); // ✅ 使用 ssd1963.h 中的初始化函数
+
+ // 注释掉重复的 lcd_init()
+ // lcd_init(); // ❌ 删除:与 ssd1963_init() 重复或冲突
+
+ // 3. 初始化 LVGL 的绘图缓冲区
+ // 参数:缓冲区结构体、第一个缓冲区、第二个缓冲区(可选)、总大小(像素数)
+ lv_disp_draw_buf_init(&draw_buf, draw_buf1, draw_buf2, LCD_WIDTH * 10);
+
+ // 4. 初始化显示驱动
+ static lv_disp_drv_t disp_drv;
+ lv_disp_drv_init(&disp_drv);
+
+ disp_drv.hor_res = LCD_WIDTH; // 水平分辨率
+ disp_drv.ver_res = LCD_HEIGHT; // 垂直分辨率
+ disp_drv.flush_cb = disp_flush; // 刷屏回调
+ disp_drv.draw_buf = &draw_buf; // 绑定缓冲区 ✅ 必须赋值!
+
+ // 5. 注册显示设备到 LVGL
+ lv_disp_drv_register(&disp_drv);
+}
diff --git a/applications/LVGL/lv_port_disp.h b/applications/LVGL/lv_port_disp.h
new file mode 100644
index 0000000..1c3675d
--- /dev/null
+++ b/applications/LVGL/lv_port_disp.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2025-10-27 Administrator the first version
+ */
+#ifndef APPLICATIONS_LV_PORT_DISP_H_
+#define APPLICATIONS_LV_PORT_DISP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define LV_COLOR_DEPTH 16
+#define LV_HOR_RES_MAX 480
+#define LV_VER_RES_MAX 272
+#define LV_DPI 130
+void ssd1963_init(void);
+void ssd1963_set_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+/**
+ * @brief 初始化 LVGL 显示驱动
+ * 调用 ssd1963_init() 并注册到 LVGL
+ */
+void lv_port_disp_init(void);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* APPLICATIONS_LV_PORT_DISP_H_ */
diff --git a/applications/LVGL/ssd1963.c b/applications/LVGL/ssd1963.c
new file mode 100644
index 0000000..1e66758
--- /dev/null
+++ b/applications/LVGL/ssd1963.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2025-10-26 Administrator the first version
+ */
+/**
+ * @file ssd1963.c
+ * @brief SSD1963 TFT LCD Controller Driver for STM32F407 + FSMC + RT-Thread
+ * @author Qwen (Generated for RTT)
+ * @date 2025-10-26
+ */
+
+#include "rtthread.h"
+#include "rtdevice.h"
+#include "ssd1963.h" // 确保路径正确
+#include
+
+
+// ==================== 引脚定义 (根据你的硬件修改) ====================
+#define LCD_RST_PIN GET_PIN(B,2) // 复位引脚
+#define LCD_BL_PIN GET_PIN(B,0) // 背光控制引脚 (PWM)
+
+// ==================== SSD1963 命令定义 ====================
+#define SSD1963_NOP 0x00
+#define SSD1963_SOFT_RESET 0x01
+#define SSD1963_GET_PWR_MODE 0x0A
+#define SSD1963_GET_ADDR_MODE 0x0B
+#define SSD1963_GET_PIX_FORMAT 0x0C
+#define SSD1963_GET_SIG_MODE 0x0D
+#define SSD1963_GET_DIAGNOSTIC 0x0F
+#define SSD1963_ENTER_SLEEP 0x10
+#define SSD1963_EXIT_SLEEP 0x11
+#define SSD1963_ENTER_PARTIAL 0x12
+#define SSD1963_ENTER_NORMAL 0x13
+#define SSD1963_EXIT_INVERT 0x20
+#define SSD1963_ENTER_INVERT 0x21
+#define SSD1963_SET_GAMMA 0x26
+#define SSD1963_BLANK_OFF 0x28
+#define SSD1963_BLANK_ON 0x29
+#define SSD1963_CLEAR_WINDOW 0x2D
+#define SSD1963_WRITE_MEMORY_START 0x2C
+#define SSD1963_READ_MEMORY 0x2E
+#define SSD1963_SET_PARTIAL_AREA 0x30
+#define SSD1963_SET_SCROLL_AREA 0x33
+#define SSD1963_SET_TEAR_OFF 0x34
+#define SSD1963_SET_TEAR_ON 0x35
+#define SSD1963_MEM_ACCESS_CTRL 0x36
+#define SSD1963_VERTICAL_SCROLL 0x37
+#define SSD1963_IDLE_OFF 0x38
+#define SSD1963_IDLE_ON 0x39
+#define SSD1963_SET_PIX_FORMAT 0x3A
+#define SSD1963_SET_IMAGE_FUNC 0x3B
+#define SSD1963_WRITE_MEMORY_CONTINUE 0x3C
+#define SSD1963_READ_MEMORY_CONTINUE 0x3E
+#define SSD1963_SET_COLUMN 0x2A
+#define SSD1963_SET_ROW 0x2B
+#define SSD1963_SET_XY 0x2C
+#define SSD1963_SET_TE_LINE 0x40
+#define SSD1963_GET_SCAN_LINE 0x45
+#define SSD1963_GET_HOR_PERIOD 0x44
+#define SSD1963_SET_PLL_MN 0xE0
+#define SSD1963_SET_PLL 0xE2
+#define SSD1963_SET_PLL_ENABLE 0xE3
+#define SSD1963_SET_DESKTOP_START 0xEA
+
+// ==================== 基础操作函数 ====================
+
+/**
+ * @brief 写入命令
+ * @param cmd 命令字节
+ */
+static void ssd1963_write_cmd(uint8_t cmd)
+{
+ SSD1963_CMD_ADDR = cmd;
+}
+
+/**
+ * @brief 写入数据字节
+ * @param data 数据字节
+ */
+static void ssd1963_write_data(uint8_t data)
+{
+ SSD1963_DATA_ADDR = data;
+}
+
+/**
+ * @brief 写入 16 位数据
+ * @param data 16 位数据
+ */
+static void ssd1963_write_data_16(uint16_t data)
+{
+ SSD1963_DATA_ADDR = data;
+}
+
+/**
+ * @brief 写入 32 位数据(分 4 次)
+ * @param data 32 位数据
+ */
+static void ssd1963_write_data_long(uint32_t data)
+{
+ ssd1963_write_data((data >> 24) & 0xFF);
+ ssd1963_write_data((data >> 16) & 0xFF);
+ ssd1963_write_data((data >> 8) & 0xFF);
+ ssd1963_write_data(data & 0xFF);
+}
+
+// ==================== 显示设置函数 ====================
+
+/**
+ * @brief 设置显示窗口(GRAM 区域)
+ * @param x1 起始 X 坐标
+ * @param y1 起始 Y 坐标
+ * @param x2 结束 X 坐标
+ * @param y2 结束 Y 坐标
+ */
+void ssd1963_set_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
+{
+ ssd1963_write_cmd(SSD1963_SET_COLUMN);
+ ssd1963_write_data_long(x1);
+ ssd1963_write_data_long(x2);
+
+ ssd1963_write_cmd(SSD1963_SET_ROW);
+ ssd1963_write_data_long(y1);
+ ssd1963_write_data_long(y2);
+
+ ssd1963_write_cmd(SSD1963_WRITE_MEMORY_START); // 准备写 GRAM
+}
+
+/**
+ * @brief 清屏
+ * @param color 填充颜色 (RGB565)
+ */
+void ssd1963_clear(rt_uint16_t color)
+{
+ uint32_t i;
+ uint32_t total_pixels = 480 * 272; // 根据实际分辨率调整
+
+ ssd1963_set_window(0, 0, 479, 271);
+ for (i = 0; i < total_pixels; i++)
+ {
+ SSD1963_DATA_ADDR = color;
+ }
+}
+
+// ==================== 初始化函数 ====================
+
+/**
+ * @brief 初始化 SSD1963 控制器
+ * 支持 480x272 分辨率,16位色
+ */
+void ssd1963_init(void)
+{
+ rt_pin_mode(LCD_RST_PIN, PIN_MODE_OUTPUT);
+
+ // 复位
+ rt_pin_write(LCD_RST_PIN, PIN_LOW);
+ rt_thread_mdelay(100);
+ rt_pin_write(LCD_RST_PIN, PIN_HIGH);
+ rt_thread_mdelay(150);
+
+ // 软件复位
+ ssd1963_write_cmd(SSD1963_SOFT_RESET);
+ rt_thread_mdelay(10);
+
+ // ============= 设置 PLL =============
+ // PLL = (CLK * (M+1)) / (N+1), 典型主频 10MHz 输入
+ ssd1963_write_cmd(SSD1963_SET_PLL_MN);
+ ssd1963_write_data(0x23); // M = 35, M+1=36
+ ssd1963_write_data(0x02); // N = 2, N+1=3
+ ssd1963_write_data(0x04); // DIV = 4
+
+ // 启用 PLL
+ ssd1963_write_cmd(SSD1963_SET_PLL_ENABLE);
+ ssd1963_write_data(0x01); // 开启 PLL
+ rt_thread_mdelay(1);
+ ssd1963_write_cmd(SSD1963_SET_PLL_ENABLE);
+ ssd1963_write_data(0x03); // 锁定 PLL
+ rt_thread_mdelay(5);
+
+ // 选择 PLL 作为系统时钟
+ ssd1963_write_cmd(SSD1963_SET_PLL);
+ ssd1963_write_data(0x03);
+
+ // ============= 设置 LCD 模式 =============
+ ssd1963_write_cmd(0xB0); // Set LCD Mode
+ ssd1963_write_data(0x20); // 24-bit/pixel, TFT 模式
+ ssd1963_write_data(0x01); // HSYNC+VSYNC 控制
+ ssd1963_write_data_long(480); // LCD 宽度
+ ssd1963_write_data_long(272); // LCD 高度
+ ssd1963_write_data_long(41); // HSYNC 脉冲宽度 (41)
+ ssd1963_write_data_long(2); // HSYNC 起始延迟 (HBP)
+ ssd1963_write_data_long(2); // HSYNC 结束延迟 (HFP)
+ ssd1963_write_data_long(10); // VSYNC 脉冲宽度 (10)
+ ssd1963_write_data_long(2); // VSYNC 起始延迟 (VBP)
+ ssd1963_write_data_long(2); // VSYNC 结束延迟 (VFP)
+
+ // ============= 设置像素格式 =============
+ ssd1963_write_cmd(SSD1963_SET_PIX_FORMAT);
+ ssd1963_write_data(0x55); // 16位色 (RGB565)
+
+ // ============= 设置内存访问方向 =============
+ ssd1963_write_cmd(SSD1963_MEM_ACCESS_CTRL);
+ ssd1963_write_data(0x08); // RGB, 正常方向
+
+ // ============= 设置背光 =============
+ // rt_pin_mode(LCD_BL_PIN, PIN_MODE_OUTPUT);
+ // rt_pwm_enable(LCD_BL_PIN);
+ // rt_pwm_set(LCD_BL_PIN, 1000, 50000); // 1kHz, 50% 占空比 (可调)
+ // rt_pin_write(LCD_BL_PIN, PIN_HIGH); // 直接输出高电平点亮
+
+ // ============= 开启显示 =============
+ ssd1963_write_cmd(SSD1963_EXIT_SLEEP);
+ rt_thread_mdelay(10);
+ ssd1963_write_cmd(SSD1963_BLANK_OFF);
+ ssd1963_write_cmd(SSD1963_ENTER_NORMAL);
+ rt_thread_mdelay(10);
+ ssd1963_write_cmd(SSD1963_IDLE_OFF);
+
+ // 初始窗口
+ ssd1963_set_window(0, 0, 799, 479);
+
+ // 可选:清屏为黑色
+ ssd1963_clear(0x00f0);
+}
+
+// ==================== LVGL 对接接口 (可选封装) ====================
+
+/**
+ * @brief 获取屏幕宽度
+ * @return 宽度
+ */
+rt_uint16_t ssd1963_get_width(void)
+{
+ return 800;
+}
+
+/**
+ * @brief 获取屏幕高度
+ * @return 高度
+ */
+rt_uint16_t ssd1963_get_height(void)
+{
+ return 480;
+}
diff --git a/applications/LVGL/ssd1963.h b/applications/LVGL/ssd1963.h
new file mode 100644
index 0000000..73fd521
--- /dev/null
+++ b/applications/LVGL/ssd1963.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2025-10-26 Administrator the first version
+ */
+#ifndef APPLICATIONS_SSD1963_H_
+#define APPLICATIONS_SSD1963_H_
+
+#include
+
+// ==================== FSMC 地址映射(必须放在头文件中供外部使用)====================
+// 假设使用 FSMC Bank1, NE1, A16 作为 RS/DC 控制线
+#define SSD1963_BASE_ADDR ((uint32_t)(0x60000000)) // FSMC_NE1
+#define LCD_CMD_ADDR (LCD_BASE_ADDR + 0x00000000) // A0 = 0
+#define LCD_DATA_ADDR (LCD_BASE_ADDR + 0x00020000) // A0 = 1
+
+// 定义 FSMC 地址:假设使用 Bank1, Base Address 0x60000000,A0 对应地址位1
+#define SSD1963_CMD_ADDR *(volatile uint16_t *)(0x60000000)
+#define SSD1963_DATA_ADDR *(volatile uint16_t *)(0x60020000)
+
+#define LCD_Write_Cmd(cmd) (*(__IO uint16_t*)LCD_CMD_ADDR = (cmd))
+#define LCD_Write_Data(dat) (*(__IO uint16_t*)LCD_DATA_ADDR = (dat))
+// 函数声明
+void ssd1963_init(void);
+void ssd1963_set_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+void ssd1963_clear(rt_uint16_t color);
+
+rt_uint16_t ssd1963_get_width(void);
+rt_uint16_t ssd1963_get_height(void);
+
+#endif /* APPLICATIONS_SSD1963_H_ */
diff --git a/applications/main.c b/applications/main.c
index dce0269..5597361 100644
--- a/applications/main.c
+++ b/applications/main.c
@@ -16,6 +16,7 @@
#include "RUN_LED.h"
#include "DB_SQLite.h"
#include "DATA_comm.h"
+#include "DATA_uart.h"
#include "uart_rs485.h"
#define DBG_TAG "main"
@@ -26,11 +27,11 @@ extern rt_sem_t mount_sem; // 引用上面SD挂载线程定义的信号量
int main(void)
{
rt_sem_take(mount_sem, rt_tick_from_millisecond(5000)); // 等待挂载完成,最多等待 5 秒
- thread_RUN_LED();//运行指示灯线程
thread_DB_SQLite();
+ rt_thread_mdelay(1000);
data_comm_init();
- app_uart_rs485_startup();
-
+ start_uart_thread();
+ thread_RUN_LED();//运行指示灯线程
return RT_EOK;
}
diff --git a/applications/mount_sdio_elmfatfs.c b/applications/mount_sdio_elmfatfs.c
index e107588..0fe1adb 100644
--- a/applications/mount_sdio_elmfatfs.c
+++ b/applications/mount_sdio_elmfatfs.c
@@ -72,7 +72,7 @@ int stm32_sdcard_mount(void)
tid = rt_thread_create("sd_mount",
sd_mount,
RT_NULL,
- 4096, // 建议增大栈,避免溢出
+ 1024*4, // 建议增大栈,避免溢出
RT_THREAD_PRIORITY_MAX - 2,
20);
if (tid != RT_NULL)
diff --git a/cubemx/.mxproject b/cubemx/.mxproject
index c73bcea..22cc31b 100644
--- a/cubemx/.mxproject
+++ b/cubemx/.mxproject
@@ -1,14 +1,14 @@
-[PreviousGenFiles]
-HeaderPath=..\Inc
-HeaderFiles=stm32f4xx_it.h;stm32f4xx_hal_conf.h;main.h;
-SourcePath=..\Src
-SourceFiles=stm32f4xx_it.c;stm32f4xx_hal_msp.c;main.c;
-
[PreviousLibFiles]
-LibFiles=Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_sdmmc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_sd.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_mmc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_bus.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_system.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_utils.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ramfunc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dmamux.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal.h;Drivers\STM32F4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_def.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_exti.h;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_sdmmc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_sd.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_mmc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ramfunc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_gpio.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_cortex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_exti.c;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_sdmmc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_sd.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_mmc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_bus.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_system.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_utils.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ramfunc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dmamux.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal.h;Drivers\STM32F4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_def.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_exti.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\stm32f407xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\system_stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\system_stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;Drivers\CMSIS\Include\cachel1_armv7.h;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm55.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_cm85.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\core_starmc1.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\pac_armv81.h;Drivers\CMSIS\Include\pmu_armv8.h;Drivers\CMSIS\Include\tz_context.h;
+LibFiles=Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_fsmc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_nor.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_sram.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_nand.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pccard.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_bus.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_system.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_utils.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ramfunc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dmamux.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal.h;Drivers\STM32F4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_def.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_sdmmc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_sd.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_mmc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_uart.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_usart.h;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_fsmc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_nor.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_sram.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_nand.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pccard.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ramfunc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_gpio.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_cortex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_exti.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_sdmmc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_sd.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_mmc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_uart.c;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_fsmc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_nor.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_sram.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_nand.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pccard.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_bus.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_system.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_utils.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ramfunc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dmamux.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal.h;Drivers\STM32F4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_def.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_sdmmc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_sd.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_mmc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_uart.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_usart.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\stm32f407xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\system_stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\system_stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;Drivers\CMSIS\Include\cachel1_armv7.h;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm55.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_cm85.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\core_starmc1.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\pac_armv81.h;Drivers\CMSIS\Include\pmu_armv8.h;Drivers\CMSIS\Include\tz_context.h;
[PreviousUsedIarFiles]
-SourceFiles=..\C:\RT-ThreadStudio\workspace\828\cubemx\Src\main.c;..\C:\RT-ThreadStudio\workspace\828\cubemx\Src\stm32f4xx_it.c;..\C:\RT-ThreadStudio\workspace\828\cubemx\Src\stm32f4xx_hal_msp.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_sdmmc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_sd.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_mmc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ramfunc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_gpio.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_cortex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_exti.c;..\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;..\\Src\system_stm32f4xx.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_sdmmc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_sd.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_mmc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ramfunc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_gpio.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_cortex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_exti.c;..\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;..\\Src\system_stm32f4xx.c;;;
+SourceFiles=..\Src\main.c;..\Src\stm32f4xx_it.c;..\Src\stm32f4xx_hal_msp.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_fsmc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_nor.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_sram.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_nand.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pccard.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ramfunc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_gpio.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_cortex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_exti.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_sdmmc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_sd.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_mmc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_uart.c;..\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;..\\Src\system_stm32f4xx.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_fsmc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_nor.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_sram.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_nand.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pccard.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ramfunc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_gpio.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_cortex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_exti.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_sdmmc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_sd.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_mmc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_uart.c;..\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;..\\Src\system_stm32f4xx.c;;;
HeaderPath=..\Drivers\STM32F4xx_HAL_Driver\Inc;..\Drivers\STM32F4xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F4xx\Include;..\Drivers\CMSIS\Include;..\Inc;
CDefines=USE_HAL_DRIVER;STM32F407xx;USE_HAL_DRIVER;USE_HAL_DRIVER;
+[PreviousGenFiles]
+HeaderPath=..\Inc
+HeaderFiles=stm32f4xx_it.h;stm32f4xx_hal_conf.h;main.h;
+SourcePath=..\Src
+SourceFiles=stm32f4xx_it.c;stm32f4xx_hal_msp.c;main.c;
+
diff --git a/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_nand.h b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_nand.h
new file mode 100644
index 0000000..9db3882
--- /dev/null
+++ b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_nand.h
@@ -0,0 +1,387 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_nand.h
+ * @author MCD Application Team
+ * @brief Header file of NAND HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32F4xx_HAL_NAND_H
+#define STM32F4xx_HAL_NAND_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(FMC_Bank3) || defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
+
+/* Includes ------------------------------------------------------------------*/
+#if defined(FSMC_Bank2_3)
+#include "stm32f4xx_ll_fsmc.h"
+#else
+#include "stm32f4xx_ll_fmc.h"
+#endif /* FSMC_Bank2_3 */
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup NAND
+ * @{
+ */
+
+/* Exported typedef ----------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup NAND_Exported_Types NAND Exported Types
+ * @{
+ */
+
+/**
+ * @brief HAL NAND State structures definition
+ */
+typedef enum
+{
+ HAL_NAND_STATE_RESET = 0x00U, /*!< NAND not yet initialized or disabled */
+ HAL_NAND_STATE_READY = 0x01U, /*!< NAND initialized and ready for use */
+ HAL_NAND_STATE_BUSY = 0x02U, /*!< NAND internal process is ongoing */
+ HAL_NAND_STATE_ERROR = 0x03U /*!< NAND error state */
+} HAL_NAND_StateTypeDef;
+
+/**
+ * @brief NAND Memory electronic signature Structure definition
+ */
+typedef struct
+{
+ /*State = HAL_NAND_STATE_RESET; \
+ (__HANDLE__)->MspInitCallback = NULL; \
+ (__HANDLE__)->MspDeInitCallback = NULL; \
+ } while(0)
+#else
+#define __HAL_NAND_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_NAND_STATE_RESET)
+#endif /* USE_HAL_NAND_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup NAND_Exported_Functions NAND Exported Functions
+ * @{
+ */
+
+/** @addtogroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+
+/* Initialization/de-initialization functions ********************************/
+HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing,
+ FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing);
+HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand);
+
+HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, const NAND_DeviceConfigTypeDef *pDeviceConfig);
+
+HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID);
+
+void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand);
+void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand);
+void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand);
+void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand);
+
+/**
+ * @}
+ */
+
+/** @addtogroup NAND_Exported_Functions_Group2 Input and Output functions
+ * @{
+ */
+
+/* IO operation functions ****************************************************/
+HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand);
+
+HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ uint8_t *pBuffer, uint32_t NumPageToRead);
+HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ const uint8_t *pBuffer, uint32_t NumPageToWrite);
+HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ uint8_t *pBuffer, uint32_t NumSpareAreaToRead);
+HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ const uint8_t *pBuffer, uint32_t NumSpareAreaTowrite);
+
+HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ uint16_t *pBuffer, uint32_t NumPageToRead);
+HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ const uint16_t *pBuffer, uint32_t NumPageToWrite);
+HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ uint16_t *pBuffer, uint32_t NumSpareAreaToRead);
+HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ const uint16_t *pBuffer, uint32_t NumSpareAreaTowrite);
+
+HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress);
+
+uint32_t HAL_NAND_Address_Inc(const NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress);
+
+#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
+/* NAND callback registering/unregistering */
+HAL_StatusTypeDef HAL_NAND_RegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId,
+ pNAND_CallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId);
+#endif /* USE_HAL_NAND_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/** @addtogroup NAND_Exported_Functions_Group3 Peripheral Control functions
+ * @{
+ */
+
+/* NAND Control functions ****************************************************/
+HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand);
+HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand);
+HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout);
+
+/**
+ * @}
+ */
+
+/** @addtogroup NAND_Exported_Functions_Group4 Peripheral State functions
+ * @{
+ */
+/* NAND State functions *******************************************************/
+HAL_NAND_StateTypeDef HAL_NAND_GetState(const NAND_HandleTypeDef *hnand);
+uint32_t HAL_NAND_Read_Status(const NAND_HandleTypeDef *hnand);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup NAND_Private_Constants NAND Private Constants
+ * @{
+ */
+#if defined(FMC_Bank2_3)
+#define NAND_DEVICE1 0x70000000UL
+#define NAND_DEVICE2 0x80000000UL
+#else
+#define NAND_DEVICE 0x80000000UL
+#endif /* FMC_Bank2_3 */
+#define NAND_WRITE_TIMEOUT 0x01000000UL
+
+#define CMD_AREA (1UL<<16U) /* A16 = CLE high */
+#define ADDR_AREA (1UL<<17U) /* A17 = ALE high */
+
+#define NAND_CMD_AREA_A ((uint8_t)0x00)
+#define NAND_CMD_AREA_B ((uint8_t)0x01)
+#define NAND_CMD_AREA_C ((uint8_t)0x50)
+#define NAND_CMD_AREA_TRUE1 ((uint8_t)0x30)
+
+#define NAND_CMD_WRITE0 ((uint8_t)0x80)
+#define NAND_CMD_WRITE_TRUE1 ((uint8_t)0x10)
+#define NAND_CMD_ERASE0 ((uint8_t)0x60)
+#define NAND_CMD_ERASE1 ((uint8_t)0xD0)
+#define NAND_CMD_READID ((uint8_t)0x90)
+#define NAND_CMD_STATUS ((uint8_t)0x70)
+#define NAND_CMD_LOCK_STATUS ((uint8_t)0x7A)
+#define NAND_CMD_RESET ((uint8_t)0xFF)
+
+/* NAND memory status */
+#define NAND_VALID_ADDRESS 0x00000100UL
+#define NAND_INVALID_ADDRESS 0x00000200UL
+#define NAND_TIMEOUT_ERROR 0x00000400UL
+#define NAND_BUSY 0x00000000UL
+#define NAND_ERROR 0x00000001UL
+#define NAND_READY 0x00000040UL
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup NAND_Private_Macros NAND Private Macros
+ * @{
+ */
+
+/**
+ * @brief NAND memory address computation.
+ * @param __ADDRESS__ NAND memory address.
+ * @param __HANDLE__ NAND handle.
+ * @retval NAND Raw address value
+ */
+#define ARRAY_ADDRESS(__ADDRESS__ , __HANDLE__) ((__ADDRESS__)->Page + \
+ (((__ADDRESS__)->Block + \
+ (((__ADDRESS__)->Plane) * \
+ ((__HANDLE__)->Config.PlaneSize))) * \
+ ((__HANDLE__)->Config.BlockSize)))
+
+/**
+ * @brief NAND memory Column address computation.
+ * @param __HANDLE__ NAND handle.
+ * @retval NAND Raw address value
+ */
+#define COLUMN_ADDRESS( __HANDLE__) ((__HANDLE__)->Config.PageSize)
+
+/**
+ * @brief NAND memory address cycling.
+ * @param __ADDRESS__ NAND memory address.
+ * @retval NAND address cycling value.
+ */
+#define ADDR_1ST_CYCLE(__ADDRESS__) (uint8_t)(__ADDRESS__) /* 1st addressing cycle */
+#define ADDR_2ND_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 8) /* 2nd addressing cycle */
+#define ADDR_3RD_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 16) /* 3rd addressing cycle */
+#define ADDR_4TH_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 24) /* 4th addressing cycle */
+
+/**
+ * @brief NAND memory Columns cycling.
+ * @param __ADDRESS__ NAND memory address.
+ * @retval NAND Column address cycling value.
+ */
+#define COLUMN_1ST_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) & 0xFFU) /* 1st Column addressing cycle */
+#define COLUMN_2ND_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 8) /* 2nd Column addressing cycle */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* FMC_Bank3) || defined(FMC_Bank2_3) || defined(FSMC_Bank2_3 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32F4xx_HAL_NAND_H */
diff --git a/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_nor.h b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_nor.h
new file mode 100644
index 0000000..427c2cc
--- /dev/null
+++ b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_nor.h
@@ -0,0 +1,330 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_nor.h
+ * @author MCD Application Team
+ * @brief Header file of NOR HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32F4xx_HAL_NOR_H
+#define STM32F4xx_HAL_NOR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(FMC_Bank1) || defined(FSMC_Bank1)
+
+/* Includes ------------------------------------------------------------------*/
+#if defined(FSMC_Bank1)
+#include "stm32f4xx_ll_fsmc.h"
+#else
+#include "stm32f4xx_ll_fmc.h"
+#endif /* FMC_Bank1 */
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup NOR
+ * @{
+ */
+
+/* Exported typedef ----------------------------------------------------------*/
+/** @defgroup NOR_Exported_Types NOR Exported Types
+ * @{
+ */
+
+/**
+ * @brief HAL SRAM State structures definition
+ */
+typedef enum
+{
+ HAL_NOR_STATE_RESET = 0x00U, /*!< NOR not yet initialized or disabled */
+ HAL_NOR_STATE_READY = 0x01U, /*!< NOR initialized and ready for use */
+ HAL_NOR_STATE_BUSY = 0x02U, /*!< NOR internal processing is ongoing */
+ HAL_NOR_STATE_ERROR = 0x03U, /*!< NOR error state */
+ HAL_NOR_STATE_PROTECTED = 0x04U /*!< NOR NORSRAM device write protected */
+} HAL_NOR_StateTypeDef;
+
+/**
+ * @brief FMC NOR Status typedef
+ */
+typedef enum
+{
+ HAL_NOR_STATUS_SUCCESS = 0U,
+ HAL_NOR_STATUS_ONGOING,
+ HAL_NOR_STATUS_ERROR,
+ HAL_NOR_STATUS_TIMEOUT
+} HAL_NOR_StatusTypeDef;
+
+/**
+ * @brief FMC NOR ID typedef
+ */
+typedef struct
+{
+ uint16_t Manufacturer_Code; /*!< Defines the device's manufacturer code used to identify the memory */
+
+ uint16_t Device_Code1;
+
+ uint16_t Device_Code2;
+
+ uint16_t Device_Code3; /*!< Defines the device's codes used to identify the memory.
+ These codes can be accessed by performing read operations with specific
+ control signals and addresses set.They can also be accessed by issuing
+ an Auto Select command */
+} NOR_IDTypeDef;
+
+/**
+ * @brief FMC NOR CFI typedef
+ */
+typedef struct
+{
+ /*!< Defines the information stored in the memory's Common flash interface
+ which contains a description of various electrical and timing parameters,
+ density information and functions supported by the memory */
+
+ uint16_t CFI_1;
+
+ uint16_t CFI_2;
+
+ uint16_t CFI_3;
+
+ uint16_t CFI_4;
+} NOR_CFITypeDef;
+
+/**
+ * @brief NOR handle Structure definition
+ */
+#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
+typedef struct __NOR_HandleTypeDef
+#else
+typedef struct
+#endif /* USE_HAL_NOR_REGISTER_CALLBACKS */
+
+{
+ FMC_NORSRAM_TypeDef *Instance; /*!< Register base address */
+
+ FMC_NORSRAM_EXTENDED_TypeDef *Extended; /*!< Extended mode register base address */
+
+ FMC_NORSRAM_InitTypeDef Init; /*!< NOR device control configuration parameters */
+
+ HAL_LockTypeDef Lock; /*!< NOR locking object */
+
+ __IO HAL_NOR_StateTypeDef State; /*!< NOR device access state */
+
+ uint32_t CommandSet; /*!< NOR algorithm command set and control */
+
+#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
+ void (* MspInitCallback)(struct __NOR_HandleTypeDef *hnor); /*!< NOR Msp Init callback */
+ void (* MspDeInitCallback)(struct __NOR_HandleTypeDef *hnor); /*!< NOR Msp DeInit callback */
+#endif /* USE_HAL_NOR_REGISTER_CALLBACKS */
+} NOR_HandleTypeDef;
+
+#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
+/**
+ * @brief HAL NOR Callback ID enumeration definition
+ */
+typedef enum
+{
+ HAL_NOR_MSP_INIT_CB_ID = 0x00U, /*!< NOR MspInit Callback ID */
+ HAL_NOR_MSP_DEINIT_CB_ID = 0x01U /*!< NOR MspDeInit Callback ID */
+} HAL_NOR_CallbackIDTypeDef;
+
+/**
+ * @brief HAL NOR Callback pointer definition
+ */
+typedef void (*pNOR_CallbackTypeDef)(NOR_HandleTypeDef *hnor);
+#endif /* USE_HAL_NOR_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup NOR_Exported_Macros NOR Exported Macros
+ * @{
+ */
+/** @brief Reset NOR handle state
+ * @param __HANDLE__ specifies the NOR handle.
+ * @retval None
+ */
+#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
+#define __HAL_NOR_RESET_HANDLE_STATE(__HANDLE__) do { \
+ (__HANDLE__)->State = HAL_NOR_STATE_RESET; \
+ (__HANDLE__)->MspInitCallback = NULL; \
+ (__HANDLE__)->MspDeInitCallback = NULL; \
+ } while(0)
+#else
+#define __HAL_NOR_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_NOR_STATE_RESET)
+#endif /* USE_HAL_NOR_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup NOR_Exported_Functions NOR Exported Functions
+ * @{
+ */
+
+/** @addtogroup NOR_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+
+/* Initialization/de-initialization functions ********************************/
+HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FMC_NORSRAM_TimingTypeDef *Timing,
+ FMC_NORSRAM_TimingTypeDef *ExtTiming);
+HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor);
+void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor);
+void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor);
+void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout);
+/**
+ * @}
+ */
+
+/** @addtogroup NOR_Exported_Functions_Group2 Input and Output functions
+ * @{
+ */
+
+/* I/O operation functions ***************************************************/
+HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID);
+HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor);
+HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData);
+HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData);
+
+HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData,
+ uint32_t uwBufferSize);
+HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData,
+ uint32_t uwBufferSize);
+
+HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address);
+HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address);
+HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI);
+
+#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
+/* NOR callback registering/unregistering */
+HAL_StatusTypeDef HAL_NOR_RegisterCallback(NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId,
+ pNOR_CallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_NOR_UnRegisterCallback(NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId);
+#endif /* USE_HAL_NOR_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @addtogroup NOR_Exported_Functions_Group3 NOR Control functions
+ * @{
+ */
+
+/* NOR Control functions *****************************************************/
+HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor);
+HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor);
+/**
+ * @}
+ */
+
+/** @addtogroup NOR_Exported_Functions_Group4 NOR State functions
+ * @{
+ */
+
+/* NOR State functions ********************************************************/
+HAL_NOR_StateTypeDef HAL_NOR_GetState(const NOR_HandleTypeDef *hnor);
+HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup NOR_Private_Constants NOR Private Constants
+ * @{
+ */
+/* NOR device IDs addresses */
+#define MC_ADDRESS ((uint16_t)0x0000)
+#define DEVICE_CODE1_ADDR ((uint16_t)0x0001)
+#define DEVICE_CODE2_ADDR ((uint16_t)0x000E)
+#define DEVICE_CODE3_ADDR ((uint16_t)0x000F)
+
+/* NOR CFI IDs addresses */
+#define CFI1_ADDRESS ((uint16_t)0x0061)
+#define CFI2_ADDRESS ((uint16_t)0x0062)
+#define CFI3_ADDRESS ((uint16_t)0x0063)
+#define CFI4_ADDRESS ((uint16_t)0x0064)
+
+/* NOR operation wait timeout */
+#define NOR_TMEOUT ((uint16_t)0xFFFF)
+
+/* NOR memory data width */
+#define NOR_MEMORY_8B ((uint8_t)0x00)
+#define NOR_MEMORY_16B ((uint8_t)0x01)
+
+/* NOR memory device read/write start address */
+#define NOR_MEMORY_ADRESS1 (0x60000000U)
+#define NOR_MEMORY_ADRESS2 (0x64000000U)
+#define NOR_MEMORY_ADRESS3 (0x68000000U)
+#define NOR_MEMORY_ADRESS4 (0x6C000000U)
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup NOR_Private_Macros NOR Private Macros
+ * @{
+ */
+/**
+ * @brief NOR memory address shifting.
+ * @param __NOR_ADDRESS NOR base address
+ * @param __NOR_MEMORY_WIDTH_ NOR memory width
+ * @param __ADDRESS__ NOR memory address
+ * @retval NOR shifted address value
+ */
+#define NOR_ADDR_SHIFT(__NOR_ADDRESS, __NOR_MEMORY_WIDTH_, __ADDRESS__) \
+ ((uint32_t)(((__NOR_MEMORY_WIDTH_) == NOR_MEMORY_16B)? \
+ ((uint32_t)((__NOR_ADDRESS) + (2U * (__ADDRESS__)))): \
+ ((uint32_t)((__NOR_ADDRESS) + (__ADDRESS__)))))
+
+/**
+ * @brief NOR memory write data to specified address.
+ * @param __ADDRESS__ NOR memory address
+ * @param __DATA__ Data to write
+ * @retval None
+ */
+#define NOR_WRITE(__ADDRESS__, __DATA__) do{ \
+ (*(__IO uint16_t *)((uint32_t)(__ADDRESS__)) = (__DATA__)); \
+ __DSB(); \
+ } while(0)
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* FMC_Bank1 || FSMC_Bank1 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32F4xx_HAL_NOR_H */
diff --git a/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pccard.h b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pccard.h
new file mode 100644
index 0000000..0be5de5
--- /dev/null
+++ b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pccard.h
@@ -0,0 +1,286 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_pccard.h
+ * @author MCD Application Team
+ * @brief Header file of PCCARD HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32F4xx_HAL_PCCARD_H
+#define STM32F4xx_HAL_PCCARD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(FMC_Bank4) || defined(FSMC_Bank4)
+
+/* Includes ------------------------------------------------------------------*/
+#if defined(FSMC_Bank4)
+#include "stm32f4xx_ll_fsmc.h"
+#else
+#include "stm32f4xx_ll_fmc.h"
+#endif /* FSMC_Bank4 */
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup PCCARD
+ * @{
+ */
+
+/* Exported typedef ----------------------------------------------------------*/
+/** @defgroup PCCARD_Exported_Types PCCARD Exported Types
+ * @{
+ */
+
+/**
+ * @brief HAL PCCARD State structures definition
+ */
+typedef enum
+{
+ HAL_PCCARD_STATE_RESET = 0x00U, /*!< PCCARD peripheral not yet initialized or disabled */
+ HAL_PCCARD_STATE_READY = 0x01U, /*!< PCCARD peripheral ready */
+ HAL_PCCARD_STATE_BUSY = 0x02U, /*!< PCCARD peripheral busy */
+ HAL_PCCARD_STATE_ERROR = 0x04U /*!< PCCARD peripheral error */
+} HAL_PCCARD_StateTypeDef;
+
+typedef enum
+{
+ HAL_PCCARD_STATUS_SUCCESS = 0U,
+ HAL_PCCARD_STATUS_ONGOING,
+ HAL_PCCARD_STATUS_ERROR,
+ HAL_PCCARD_STATUS_TIMEOUT
+} HAL_PCCARD_StatusTypeDef;
+
+/**
+ * @brief FMC_PCCARD handle Structure definition
+ */
+#if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
+typedef struct __PCCARD_HandleTypeDef
+#else
+typedef struct
+#endif /* USE_HAL_PCCARD_REGISTER_CALLBACKS */
+{
+ FMC_PCCARD_TypeDef *Instance; /*!< Register base address for PCCARD device */
+
+ FMC_PCCARD_InitTypeDef Init; /*!< PCCARD device control configuration parameters */
+
+ __IO HAL_PCCARD_StateTypeDef State; /*!< PCCARD device access state */
+
+ HAL_LockTypeDef Lock; /*!< PCCARD Lock */
+
+#if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
+ void (* MspInitCallback)(struct __PCCARD_HandleTypeDef *hpccard); /*!< PCCARD Msp Init callback */
+ void (* MspDeInitCallback)(struct __PCCARD_HandleTypeDef *hpccard); /*!< PCCARD Msp DeInit callback */
+ void (* ItCallback)(struct __PCCARD_HandleTypeDef *hpccard); /*!< PCCARD IT callback */
+#endif /* USE_HAL_PCCARD_REGISTER_CALLBACKS */
+} PCCARD_HandleTypeDef;
+
+#if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
+/**
+ * @brief HAL PCCARD Callback ID enumeration definition
+ */
+typedef enum
+{
+ HAL_PCCARD_MSP_INIT_CB_ID = 0x00U, /*!< PCCARD MspInit Callback ID */
+ HAL_PCCARD_MSP_DEINIT_CB_ID = 0x01U, /*!< PCCARD MspDeInit Callback ID */
+ HAL_PCCARD_IT_CB_ID = 0x02U /*!< PCCARD IT Callback ID */
+} HAL_PCCARD_CallbackIDTypeDef;
+
+/**
+ * @brief HAL PCCARD Callback pointer definition
+ */
+typedef void (*pPCCARD_CallbackTypeDef)(PCCARD_HandleTypeDef *hpccard);
+#endif /* USE_HAL_PCCARD_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup PCCARD_Exported_Macros PCCARD Exported Macros
+ * @{
+ */
+/** @brief Reset PCCARD handle state
+ * @param __HANDLE__ specifies the PCCARD handle.
+ * @retval None
+ */
+#if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
+#define __HAL_PCCARD_RESET_HANDLE_STATE(__HANDLE__) do { \
+ (__HANDLE__)->State = HAL_PCCARD_STATE_RESET; \
+ (__HANDLE__)->MspInitCallback = NULL; \
+ (__HANDLE__)->MspDeInitCallback = NULL; \
+ } while(0)
+#else
+#define __HAL_PCCARD_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_PCCARD_STATE_RESET)
+#endif /* USE_HAL_PCCARD_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup PCCARD_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup PCCARD_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_PCCARD_Init(PCCARD_HandleTypeDef *hpccard, FMC_NAND_PCC_TimingTypeDef *ComSpaceTiming,
+ FMC_NAND_PCC_TimingTypeDef *AttSpaceTiming,
+ FMC_NAND_PCC_TimingTypeDef *IOSpaceTiming);
+HAL_StatusTypeDef HAL_PCCARD_DeInit(PCCARD_HandleTypeDef *hpccard);
+void HAL_PCCARD_MspInit(PCCARD_HandleTypeDef *hpccard);
+void HAL_PCCARD_MspDeInit(PCCARD_HandleTypeDef *hpccard);
+/**
+ * @}
+ */
+
+/** @addtogroup PCCARD_Exported_Functions_Group2
+ * @{
+ */
+/* IO operation functions *****************************************************/
+HAL_StatusTypeDef HAL_PCCARD_Read_ID(PCCARD_HandleTypeDef *hpccard, uint8_t CompactFlash_ID[], uint8_t *pStatus);
+HAL_StatusTypeDef HAL_PCCARD_Write_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress,
+ uint8_t *pStatus);
+HAL_StatusTypeDef HAL_PCCARD_Read_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress,
+ uint8_t *pStatus);
+HAL_StatusTypeDef HAL_PCCARD_Erase_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t SectorAddress, uint8_t *pStatus);
+HAL_StatusTypeDef HAL_PCCARD_Reset(PCCARD_HandleTypeDef *hpccard);
+void HAL_PCCARD_IRQHandler(PCCARD_HandleTypeDef *hpccard);
+void HAL_PCCARD_ITCallback(PCCARD_HandleTypeDef *hpccard);
+
+#if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
+/* PCCARD callback registering/unregistering */
+HAL_StatusTypeDef HAL_PCCARD_RegisterCallback(PCCARD_HandleTypeDef *hpccard, HAL_PCCARD_CallbackIDTypeDef CallbackId,
+ pPCCARD_CallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_PCCARD_UnRegisterCallback(PCCARD_HandleTypeDef *hpccard,
+ HAL_PCCARD_CallbackIDTypeDef CallbackId);
+#endif /* USE_HAL_PCCARD_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @addtogroup PCCARD_Exported_Functions_Group3
+ * @{
+ */
+/* PCCARD State functions *******************************************************/
+HAL_PCCARD_StateTypeDef HAL_PCCARD_GetState(PCCARD_HandleTypeDef *hpccard);
+HAL_PCCARD_StatusTypeDef HAL_PCCARD_GetStatus(PCCARD_HandleTypeDef *hpccard);
+HAL_PCCARD_StatusTypeDef HAL_PCCARD_ReadStatus(PCCARD_HandleTypeDef *hpccard);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup PCCARD_Private_Constants PCCARD Private Constants
+ * @{
+ */
+#define PCCARD_DEVICE_ADDRESS 0x90000000U
+#define PCCARD_ATTRIBUTE_SPACE_ADDRESS 0x98000000U /* Attribute space size to @0x9BFF FFFF */
+#define PCCARD_COMMON_SPACE_ADDRESS PCCARD_DEVICE_ADDRESS /* Common space size to @0x93FF FFFF */
+#define PCCARD_IO_SPACE_ADDRESS 0x9C000000U /* IO space size to @0x9FFF FFFF */
+#define PCCARD_IO_SPACE_PRIMARY_ADDR 0x9C0001F0U /* IO space size to @0x9FFF FFFF */
+
+/* Flash-ATA registers description */
+#define ATA_DATA ((uint8_t)0x00) /* Data register */
+#define ATA_SECTOR_COUNT ((uint8_t)0x02) /* Sector Count register */
+#define ATA_SECTOR_NUMBER ((uint8_t)0x03) /* Sector Number register */
+#define ATA_CYLINDER_LOW ((uint8_t)0x04) /* Cylinder low register */
+#define ATA_CYLINDER_HIGH ((uint8_t)0x05) /* Cylinder high register */
+#define ATA_CARD_HEAD ((uint8_t)0x06) /* Card/Head register */
+#define ATA_STATUS_CMD ((uint8_t)0x07) /* Status(read)/Command(write) register */
+#define ATA_STATUS_CMD_ALTERNATE ((uint8_t)0x0E) /* Alternate Status(read)/Command(write) register */
+#define ATA_COMMON_DATA_AREA ((uint16_t)0x0400) /* Start of data area (for Common access only!) */
+#define ATA_CARD_CONFIGURATION ((uint16_t)0x0202) /* Card Configuration and Status Register */
+
+/* Flash-ATA commands */
+#define ATA_READ_SECTOR_CMD ((uint8_t)0x20)
+#define ATA_WRITE_SECTOR_CMD ((uint8_t)0x30)
+#define ATA_ERASE_SECTOR_CMD ((uint8_t)0xC0)
+#define ATA_IDENTIFY_CMD ((uint8_t)0xEC)
+
+/* PC Card/Compact Flash status */
+#define PCCARD_TIMEOUT_ERROR ((uint8_t)0x60)
+#define PCCARD_BUSY ((uint8_t)0x80)
+#define PCCARD_PROGR ((uint8_t)0x01)
+#define PCCARD_READY ((uint8_t)0x40)
+
+#define PCCARD_SECTOR_SIZE 255U /* In half words */
+
+/**
+ * @}
+ */
+/* Compact Flash redefinition */
+#define HAL_CF_Init HAL_PCCARD_Init
+#define HAL_CF_DeInit HAL_PCCARD_DeInit
+#define HAL_CF_MspInit HAL_PCCARD_MspInit
+#define HAL_CF_MspDeInit HAL_PCCARD_MspDeInit
+
+#define HAL_CF_Read_ID HAL_PCCARD_Read_ID
+#define HAL_CF_Write_Sector HAL_PCCARD_Write_Sector
+#define HAL_CF_Read_Sector HAL_PCCARD_Read_Sector
+#define HAL_CF_Erase_Sector HAL_PCCARD_Erase_Sector
+#define HAL_CF_Reset HAL_PCCARD_Reset
+#define HAL_CF_IRQHandler HAL_PCCARD_IRQHandler
+#define HAL_CF_ITCallback HAL_PCCARD_ITCallback
+
+#define HAL_CF_GetState HAL_PCCARD_GetState
+#define HAL_CF_GetStatus HAL_PCCARD_GetStatus
+#define HAL_CF_ReadStatus HAL_PCCARD_ReadStatus
+
+#define HAL_CF_STATUS_SUCCESS HAL_PCCARD_STATUS_SUCCESS
+#define HAL_CF_STATUS_ONGOING HAL_PCCARD_STATUS_ONGOING
+#define HAL_CF_STATUS_ERROR HAL_PCCARD_STATUS_ERROR
+#define HAL_CF_STATUS_TIMEOUT HAL_PCCARD_STATUS_TIMEOUT
+#define HAL_CF_StatusTypeDef HAL_PCCARD_StatusTypeDef
+
+#define CF_DEVICE_ADDRESS PCCARD_DEVICE_ADDRESS
+#define CF_ATTRIBUTE_SPACE_ADDRESS PCCARD_ATTRIBUTE_SPACE_ADDRESS
+#define CF_COMMON_SPACE_ADDRESS PCCARD_COMMON_SPACE_ADDRESS
+#define CF_IO_SPACE_ADDRESS PCCARD_IO_SPACE_ADDRESS
+#define CF_IO_SPACE_PRIMARY_ADDR PCCARD_IO_SPACE_PRIMARY_ADDR
+
+#define CF_TIMEOUT_ERROR PCCARD_TIMEOUT_ERROR
+#define CF_BUSY PCCARD_BUSY
+#define CF_PROGR PCCARD_PROGR
+#define CF_READY PCCARD_READY
+
+#define CF_SECTOR_SIZE PCCARD_SECTOR_SIZE
+
+/* Private macros ------------------------------------------------------------*/
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+#endif /* FMC_Bank4 || FSMC_Bank4 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32F4xx_HAL_PCCARD_H */
diff --git a/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sram.h b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sram.h
new file mode 100644
index 0000000..a6e6111
--- /dev/null
+++ b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sram.h
@@ -0,0 +1,236 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_sram.h
+ * @author MCD Application Team
+ * @brief Header file of SRAM HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32F4xx_HAL_SRAM_H
+#define STM32F4xx_HAL_SRAM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(FMC_Bank1) || defined(FSMC_Bank1)
+
+/* Includes ------------------------------------------------------------------*/
+#if defined(FSMC_Bank1)
+#include "stm32f4xx_ll_fsmc.h"
+#else
+#include "stm32f4xx_ll_fmc.h"
+#endif /* FSMC_Bank1 */
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+/** @addtogroup SRAM
+ * @{
+ */
+
+/* Exported typedef ----------------------------------------------------------*/
+
+/** @defgroup SRAM_Exported_Types SRAM Exported Types
+ * @{
+ */
+/**
+ * @brief HAL SRAM State structures definition
+ */
+typedef enum
+{
+ HAL_SRAM_STATE_RESET = 0x00U, /*!< SRAM not yet initialized or disabled */
+ HAL_SRAM_STATE_READY = 0x01U, /*!< SRAM initialized and ready for use */
+ HAL_SRAM_STATE_BUSY = 0x02U, /*!< SRAM internal process is ongoing */
+ HAL_SRAM_STATE_ERROR = 0x03U, /*!< SRAM error state */
+ HAL_SRAM_STATE_PROTECTED = 0x04U /*!< SRAM peripheral NORSRAM device write protected */
+
+} HAL_SRAM_StateTypeDef;
+
+/**
+ * @brief SRAM handle Structure definition
+ */
+#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
+typedef struct __SRAM_HandleTypeDef
+#else
+typedef struct
+#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
+{
+ FMC_NORSRAM_TypeDef *Instance; /*!< Register base address */
+
+ FMC_NORSRAM_EXTENDED_TypeDef *Extended; /*!< Extended mode register base address */
+
+ FMC_NORSRAM_InitTypeDef Init; /*!< SRAM device control configuration parameters */
+
+ HAL_LockTypeDef Lock; /*!< SRAM locking object */
+
+ __IO HAL_SRAM_StateTypeDef State; /*!< SRAM device access state */
+
+ DMA_HandleTypeDef *hdma; /*!< Pointer DMA handler */
+
+#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
+ void (* MspInitCallback)(struct __SRAM_HandleTypeDef *hsram); /*!< SRAM Msp Init callback */
+ void (* MspDeInitCallback)(struct __SRAM_HandleTypeDef *hsram); /*!< SRAM Msp DeInit callback */
+ void (* DmaXferCpltCallback)(DMA_HandleTypeDef *hdma); /*!< SRAM DMA Xfer Complete callback */
+ void (* DmaXferErrorCallback)(DMA_HandleTypeDef *hdma); /*!< SRAM DMA Xfer Error callback */
+#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
+} SRAM_HandleTypeDef;
+
+#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
+/**
+ * @brief HAL SRAM Callback ID enumeration definition
+ */
+typedef enum
+{
+ HAL_SRAM_MSP_INIT_CB_ID = 0x00U, /*!< SRAM MspInit Callback ID */
+ HAL_SRAM_MSP_DEINIT_CB_ID = 0x01U, /*!< SRAM MspDeInit Callback ID */
+ HAL_SRAM_DMA_XFER_CPLT_CB_ID = 0x02U, /*!< SRAM DMA Xfer Complete Callback ID */
+ HAL_SRAM_DMA_XFER_ERR_CB_ID = 0x03U /*!< SRAM DMA Xfer Complete Callback ID */
+} HAL_SRAM_CallbackIDTypeDef;
+
+/**
+ * @brief HAL SRAM Callback pointer definition
+ */
+typedef void (*pSRAM_CallbackTypeDef)(SRAM_HandleTypeDef *hsram);
+typedef void (*pSRAM_DmaCallbackTypeDef)(DMA_HandleTypeDef *hdma);
+#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup SRAM_Exported_Macros SRAM Exported Macros
+ * @{
+ */
+
+/** @brief Reset SRAM handle state
+ * @param __HANDLE__ SRAM handle
+ * @retval None
+ */
+#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
+#define __HAL_SRAM_RESET_HANDLE_STATE(__HANDLE__) do { \
+ (__HANDLE__)->State = HAL_SRAM_STATE_RESET; \
+ (__HANDLE__)->MspInitCallback = NULL; \
+ (__HANDLE__)->MspDeInitCallback = NULL; \
+ } while(0)
+#else
+#define __HAL_SRAM_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SRAM_STATE_RESET)
+#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup SRAM_Exported_Functions SRAM Exported Functions
+ * @{
+ */
+
+/** @addtogroup SRAM_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+
+/* Initialization/de-initialization functions ********************************/
+HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FMC_NORSRAM_TimingTypeDef *Timing,
+ FMC_NORSRAM_TimingTypeDef *ExtTiming);
+HAL_StatusTypeDef HAL_SRAM_DeInit(SRAM_HandleTypeDef *hsram);
+void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram);
+void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram);
+
+/**
+ * @}
+ */
+
+/** @addtogroup SRAM_Exported_Functions_Group2 Input Output and memory control functions
+ * @{
+ */
+
+/* I/O operation functions ***************************************************/
+HAL_StatusTypeDef HAL_SRAM_Read_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pDstBuffer,
+ uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Write_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pSrcBuffer,
+ uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pDstBuffer,
+ uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pSrcBuffer,
+ uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer,
+ uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Write_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer,
+ uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Read_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer,
+ uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Write_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer,
+ uint32_t BufferSize);
+
+void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma);
+void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma);
+
+#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
+/* SRAM callback registering/unregistering */
+HAL_StatusTypeDef HAL_SRAM_RegisterCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId,
+ pSRAM_CallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_SRAM_UnRegisterCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId);
+HAL_StatusTypeDef HAL_SRAM_RegisterDmaCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId,
+ pSRAM_DmaCallbackTypeDef pCallback);
+#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/** @addtogroup SRAM_Exported_Functions_Group3 Control functions
+ * @{
+ */
+
+/* SRAM Control functions ****************************************************/
+HAL_StatusTypeDef HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram);
+HAL_StatusTypeDef HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram);
+
+/**
+ * @}
+ */
+
+/** @addtogroup SRAM_Exported_Functions_Group4 Peripheral State functions
+ * @{
+ */
+
+/* SRAM State functions ******************************************************/
+HAL_SRAM_StateTypeDef HAL_SRAM_GetState(const SRAM_HandleTypeDef *hsram);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* FMC_Bank1 || FSMC_Bank1 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32F4xx_HAL_SRAM_H */
diff --git a/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h
new file mode 100644
index 0000000..e6ce82f
--- /dev/null
+++ b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h
@@ -0,0 +1,909 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_uart.h
+ * @author MCD Application Team
+ * @brief Header file of UART HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_UART_H
+#define __STM32F4xx_HAL_UART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal_def.h"
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup UART
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup UART_Exported_Types UART Exported Types
+ * @{
+ */
+
+/**
+ * @brief UART Init Structure definition
+ */
+typedef struct
+{
+ uint32_t BaudRate; /*!< This member configures the UART communication baud rate.
+ The baud rate is computed using the following formula:
+ - IntegerDivider = ((PCLKx) / (8 * (OVR8+1) * (huart->Init.BaudRate)))
+ - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 8 * (OVR8+1)) + 0.5
+ Where OVR8 is the "oversampling by 8 mode" configuration bit in the CR1 register. */
+
+ uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
+ This parameter can be a value of @ref UART_Word_Length */
+
+ uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
+ This parameter can be a value of @ref UART_Stop_Bits */
+
+ uint32_t Parity; /*!< Specifies the parity mode.
+ This parameter can be a value of @ref UART_Parity
+ @note When parity is enabled, the computed parity is inserted
+ at the MSB position of the transmitted data (9th bit when
+ the word length is set to 9 data bits; 8th bit when the
+ word length is set to 8 data bits). */
+
+ uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
+ This parameter can be a value of @ref UART_Mode */
+
+ uint32_t HwFlowCtl; /*!< Specifies whether the hardware flow control mode is enabled or disabled.
+ This parameter can be a value of @ref UART_Hardware_Flow_Control */
+
+ uint32_t OverSampling; /*!< Specifies whether the Over sampling 8 is enabled or disabled, to achieve higher speed (up to fPCLK/8).
+ This parameter can be a value of @ref UART_Over_Sampling */
+} UART_InitTypeDef;
+
+/**
+ * @brief HAL UART State structures definition
+ * @note HAL UART State value is a combination of 2 different substates: gState and RxState.
+ * - gState contains UART state information related to global Handle management
+ * and also information related to Tx operations.
+ * gState value coding follow below described bitmap :
+ * b7-b6 Error information
+ * 00 : No Error
+ * 01 : (Not Used)
+ * 10 : Timeout
+ * 11 : Error
+ * b5 Peripheral initialization status
+ * 0 : Reset (Peripheral not initialized)
+ * 1 : Init done (Peripheral initialized. HAL UART Init function already called)
+ * b4-b3 (not used)
+ * xx : Should be set to 00
+ * b2 Intrinsic process state
+ * 0 : Ready
+ * 1 : Busy (Peripheral busy with some configuration or internal operations)
+ * b1 (not used)
+ * x : Should be set to 0
+ * b0 Tx state
+ * 0 : Ready (no Tx operation ongoing)
+ * 1 : Busy (Tx operation ongoing)
+ * - RxState contains information related to Rx operations.
+ * RxState value coding follow below described bitmap :
+ * b7-b6 (not used)
+ * xx : Should be set to 00
+ * b5 Peripheral initialization status
+ * 0 : Reset (Peripheral not initialized)
+ * 1 : Init done (Peripheral initialized)
+ * b4-b2 (not used)
+ * xxx : Should be set to 000
+ * b1 Rx state
+ * 0 : Ready (no Rx operation ongoing)
+ * 1 : Busy (Rx operation ongoing)
+ * b0 (not used)
+ * x : Should be set to 0.
+ */
+typedef enum
+{
+ HAL_UART_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized
+ Value is allowed for gState and RxState */
+ HAL_UART_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use
+ Value is allowed for gState and RxState */
+ HAL_UART_STATE_BUSY = 0x24U, /*!< an internal process is ongoing
+ Value is allowed for gState only */
+ HAL_UART_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing
+ Value is allowed for gState only */
+ HAL_UART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing
+ Value is allowed for RxState only */
+ HAL_UART_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing
+ Not to be used for neither gState nor RxState.
+ Value is result of combination (Or) between gState and RxState values */
+ HAL_UART_STATE_TIMEOUT = 0xA0U, /*!< Timeout state
+ Value is allowed for gState only */
+ HAL_UART_STATE_ERROR = 0xE0U /*!< Error
+ Value is allowed for gState only */
+} HAL_UART_StateTypeDef;
+
+/**
+ * @brief HAL UART Reception type definition
+ * @note HAL UART Reception type value aims to identify which type of Reception is ongoing.
+ * This parameter can be a value of @ref UART_Reception_Type_Values :
+ * HAL_UART_RECEPTION_STANDARD = 0x00U,
+ * HAL_UART_RECEPTION_TOIDLE = 0x01U,
+ */
+typedef uint32_t HAL_UART_RxTypeTypeDef;
+
+/**
+ * @brief HAL UART Rx Event type definition
+ * @note HAL UART Rx Event type value aims to identify which type of Event has occurred
+ * leading to call of the RxEvent callback.
+ * This parameter can be a value of @ref UART_RxEvent_Type_Values :
+ * HAL_UART_RXEVENT_TC = 0x00U,
+ * HAL_UART_RXEVENT_HT = 0x01U,
+ * HAL_UART_RXEVENT_IDLE = 0x02U,
+ */
+typedef uint32_t HAL_UART_RxEventTypeTypeDef;
+
+/**
+ * @brief UART handle Structure definition
+ */
+typedef struct __UART_HandleTypeDef
+{
+ USART_TypeDef *Instance; /*!< UART registers base address */
+
+ UART_InitTypeDef Init; /*!< UART communication parameters */
+
+ const uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */
+
+ uint16_t TxXferSize; /*!< UART Tx Transfer size */
+
+ __IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */
+
+ uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */
+
+ uint16_t RxXferSize; /*!< UART Rx Transfer size */
+
+ __IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */
+
+ __IO HAL_UART_RxTypeTypeDef ReceptionType; /*!< Type of ongoing reception */
+
+ __IO HAL_UART_RxEventTypeTypeDef RxEventType; /*!< Type of Rx Event */
+
+ DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */
+
+ DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */
+
+ HAL_LockTypeDef Lock; /*!< Locking object */
+
+ __IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management
+ and also related to Tx operations.
+ This parameter can be a value of @ref HAL_UART_StateTypeDef */
+
+ __IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations.
+ This parameter can be a value of @ref HAL_UART_StateTypeDef */
+
+ __IO uint32_t ErrorCode; /*!< UART Error code */
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ void (* TxHalfCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Half Complete Callback */
+ void (* TxCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Complete Callback */
+ void (* RxHalfCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Half Complete Callback */
+ void (* RxCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Complete Callback */
+ void (* ErrorCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Error Callback */
+ void (* AbortCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Complete Callback */
+ void (* AbortTransmitCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Transmit Complete Callback */
+ void (* AbortReceiveCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Receive Complete Callback */
+ void (* WakeupCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Wakeup Callback */
+ void (* RxEventCallback)(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< UART Reception Event Callback */
+
+ void (* MspInitCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Msp Init callback */
+ void (* MspDeInitCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Msp DeInit callback */
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+} UART_HandleTypeDef;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+/**
+ * @brief HAL UART Callback ID enumeration definition
+ */
+typedef enum
+{
+ HAL_UART_TX_HALFCOMPLETE_CB_ID = 0x00U, /*!< UART Tx Half Complete Callback ID */
+ HAL_UART_TX_COMPLETE_CB_ID = 0x01U, /*!< UART Tx Complete Callback ID */
+ HAL_UART_RX_HALFCOMPLETE_CB_ID = 0x02U, /*!< UART Rx Half Complete Callback ID */
+ HAL_UART_RX_COMPLETE_CB_ID = 0x03U, /*!< UART Rx Complete Callback ID */
+ HAL_UART_ERROR_CB_ID = 0x04U, /*!< UART Error Callback ID */
+ HAL_UART_ABORT_COMPLETE_CB_ID = 0x05U, /*!< UART Abort Complete Callback ID */
+ HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID = 0x06U, /*!< UART Abort Transmit Complete Callback ID */
+ HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID = 0x07U, /*!< UART Abort Receive Complete Callback ID */
+ HAL_UART_WAKEUP_CB_ID = 0x08U, /*!< UART Wakeup Callback ID */
+
+ HAL_UART_MSPINIT_CB_ID = 0x0BU, /*!< UART MspInit callback ID */
+ HAL_UART_MSPDEINIT_CB_ID = 0x0CU /*!< UART MspDeInit callback ID */
+
+} HAL_UART_CallbackIDTypeDef;
+
+/**
+ * @brief HAL UART Callback pointer definition
+ */
+typedef void (*pUART_CallbackTypeDef)(UART_HandleTypeDef *huart); /*!< pointer to an UART callback function */
+typedef void (*pUART_RxEventCallbackTypeDef)(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< pointer to a UART Rx Event specific callback function */
+
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup UART_Exported_Constants UART Exported Constants
+ * @{
+ */
+
+/** @defgroup UART_Error_Code UART Error Code
+ * @{
+ */
+#define HAL_UART_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_UART_ERROR_PE 0x00000001U /*!< Parity error */
+#define HAL_UART_ERROR_NE 0x00000002U /*!< Noise error */
+#define HAL_UART_ERROR_FE 0x00000004U /*!< Frame error */
+#define HAL_UART_ERROR_ORE 0x00000008U /*!< Overrun error */
+#define HAL_UART_ERROR_DMA 0x00000010U /*!< DMA transfer error */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+#define HAL_UART_ERROR_INVALID_CALLBACK 0x00000020U /*!< Invalid Callback error */
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @defgroup UART_Word_Length UART Word Length
+ * @{
+ */
+#define UART_WORDLENGTH_8B 0x00000000U
+#define UART_WORDLENGTH_9B ((uint32_t)USART_CR1_M)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Stop_Bits UART Number of Stop Bits
+ * @{
+ */
+#define UART_STOPBITS_1 0x00000000U
+#define UART_STOPBITS_2 ((uint32_t)USART_CR2_STOP_1)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Parity UART Parity
+ * @{
+ */
+#define UART_PARITY_NONE 0x00000000U
+#define UART_PARITY_EVEN ((uint32_t)USART_CR1_PCE)
+#define UART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS))
+/**
+ * @}
+ */
+
+/** @defgroup UART_Hardware_Flow_Control UART Hardware Flow Control
+ * @{
+ */
+#define UART_HWCONTROL_NONE 0x00000000U
+#define UART_HWCONTROL_RTS ((uint32_t)USART_CR3_RTSE)
+#define UART_HWCONTROL_CTS ((uint32_t)USART_CR3_CTSE)
+#define UART_HWCONTROL_RTS_CTS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE))
+/**
+ * @}
+ */
+
+/** @defgroup UART_Mode UART Transfer Mode
+ * @{
+ */
+#define UART_MODE_RX ((uint32_t)USART_CR1_RE)
+#define UART_MODE_TX ((uint32_t)USART_CR1_TE)
+#define UART_MODE_TX_RX ((uint32_t)(USART_CR1_TE | USART_CR1_RE))
+/**
+ * @}
+ */
+
+/** @defgroup UART_State UART State
+ * @{
+ */
+#define UART_STATE_DISABLE 0x00000000U
+#define UART_STATE_ENABLE ((uint32_t)USART_CR1_UE)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Over_Sampling UART Over Sampling
+ * @{
+ */
+#define UART_OVERSAMPLING_16 0x00000000U
+#define UART_OVERSAMPLING_8 ((uint32_t)USART_CR1_OVER8)
+/**
+ * @}
+ */
+
+/** @defgroup UART_LIN_Break_Detection_Length UART LIN Break Detection Length
+ * @{
+ */
+#define UART_LINBREAKDETECTLENGTH_10B 0x00000000U
+#define UART_LINBREAKDETECTLENGTH_11B ((uint32_t)USART_CR2_LBDL)
+/**
+ * @}
+ */
+
+/** @defgroup UART_WakeUp_functions UART Wakeup Functions
+ * @{
+ */
+#define UART_WAKEUPMETHOD_IDLELINE 0x00000000U
+#define UART_WAKEUPMETHOD_ADDRESSMARK ((uint32_t)USART_CR1_WAKE)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Flags UART FLags
+ * Elements values convention: 0xXXXX
+ * - 0xXXXX : Flag mask in the SR register
+ * @{
+ */
+#define UART_FLAG_CTS ((uint32_t)USART_SR_CTS)
+#define UART_FLAG_LBD ((uint32_t)USART_SR_LBD)
+#define UART_FLAG_TXE ((uint32_t)USART_SR_TXE)
+#define UART_FLAG_TC ((uint32_t)USART_SR_TC)
+#define UART_FLAG_RXNE ((uint32_t)USART_SR_RXNE)
+#define UART_FLAG_IDLE ((uint32_t)USART_SR_IDLE)
+#define UART_FLAG_ORE ((uint32_t)USART_SR_ORE)
+#define UART_FLAG_NE ((uint32_t)USART_SR_NE)
+#define UART_FLAG_FE ((uint32_t)USART_SR_FE)
+#define UART_FLAG_PE ((uint32_t)USART_SR_PE)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Interrupt_definition UART Interrupt Definitions
+ * Elements values convention: 0xY000XXXX
+ * - XXXX : Interrupt mask (16 bits) in the Y register
+ * - Y : Interrupt source register (2bits)
+ * - 0001: CR1 register
+ * - 0010: CR2 register
+ * - 0011: CR3 register
+ * @{
+ */
+
+#define UART_IT_PE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_PEIE))
+#define UART_IT_TXE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_TXEIE))
+#define UART_IT_TC ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_TCIE))
+#define UART_IT_RXNE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_RXNEIE))
+#define UART_IT_IDLE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_IDLEIE))
+
+#define UART_IT_LBD ((uint32_t)(UART_CR2_REG_INDEX << 28U | USART_CR2_LBDIE))
+
+#define UART_IT_CTS ((uint32_t)(UART_CR3_REG_INDEX << 28U | USART_CR3_CTSIE))
+#define UART_IT_ERR ((uint32_t)(UART_CR3_REG_INDEX << 28U | USART_CR3_EIE))
+/**
+ * @}
+ */
+
+/** @defgroup UART_Reception_Type_Values UART Reception type values
+ * @{
+ */
+#define HAL_UART_RECEPTION_STANDARD (0x00000000U) /*!< Standard reception */
+#define HAL_UART_RECEPTION_TOIDLE (0x00000001U) /*!< Reception till completion or IDLE event */
+/**
+ * @}
+ */
+
+/** @defgroup UART_RxEvent_Type_Values UART RxEvent type values
+ * @{
+ */
+#define HAL_UART_RXEVENT_TC (0x00000000U) /*!< RxEvent linked to Transfer Complete event */
+#define HAL_UART_RXEVENT_HT (0x00000001U) /*!< RxEvent linked to Half Transfer event */
+#define HAL_UART_RXEVENT_IDLE (0x00000002U)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup UART_Exported_Macros UART Exported Macros
+ * @{
+ */
+
+/** @brief Reset UART handle gstate & RxState
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @retval None
+ */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) do{ \
+ (__HANDLE__)->gState = HAL_UART_STATE_RESET; \
+ (__HANDLE__)->RxState = HAL_UART_STATE_RESET; \
+ (__HANDLE__)->MspInitCallback = NULL; \
+ (__HANDLE__)->MspDeInitCallback = NULL; \
+ } while(0U)
+#else
+#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) do{ \
+ (__HANDLE__)->gState = HAL_UART_STATE_RESET; \
+ (__HANDLE__)->RxState = HAL_UART_STATE_RESET; \
+ } while(0U)
+#endif /*USE_HAL_UART_REGISTER_CALLBACKS */
+
+/** @brief Flushes the UART DR register
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_UART_FLUSH_DRREGISTER(__HANDLE__) ((__HANDLE__)->Instance->DR)
+
+/** @brief Checks whether the specified UART flag is set or not.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5)
+ * @arg UART_FLAG_LBD: LIN Break detection flag
+ * @arg UART_FLAG_TXE: Transmit data register empty flag
+ * @arg UART_FLAG_TC: Transmission Complete flag
+ * @arg UART_FLAG_RXNE: Receive data register not empty flag
+ * @arg UART_FLAG_IDLE: Idle Line detection flag
+ * @arg UART_FLAG_ORE: Overrun Error flag
+ * @arg UART_FLAG_NE: Noise Error flag
+ * @arg UART_FLAG_FE: Framing Error flag
+ * @arg UART_FLAG_PE: Parity Error flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clears the specified UART pending flag.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be any combination of the following values:
+ * @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5).
+ * @arg UART_FLAG_LBD: LIN Break detection flag.
+ * @arg UART_FLAG_TC: Transmission Complete flag.
+ * @arg UART_FLAG_RXNE: Receive data register not empty flag.
+ *
+ * @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (Overrun
+ * error) and IDLE (Idle line detected) flags are cleared by software
+ * sequence: a read operation to USART_SR register followed by a read
+ * operation to USART_DR register.
+ * @note RXNE flag can be also cleared by a read to the USART_DR register.
+ * @note TC flag can be also cleared by software sequence: a read operation to
+ * USART_SR register followed by a write operation to USART_DR register.
+ * @note TXE flag is cleared only by a write to the USART_DR register.
+ *
+ * @retval None
+ */
+#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__))
+
+/** @brief Clears the UART PE pending flag.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @retval None
+ */
+#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->SR; \
+ tmpreg = (__HANDLE__)->Instance->DR; \
+ UNUSED(tmpreg); \
+ } while(0U)
+
+/** @brief Clears the UART FE pending flag.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @retval None
+ */
+#define __HAL_UART_CLEAR_FEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clears the UART NE pending flag.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @retval None
+ */
+#define __HAL_UART_CLEAR_NEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clears the UART ORE pending flag.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @retval None
+ */
+#define __HAL_UART_CLEAR_OREFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clears the UART IDLE pending flag.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @retval None
+ */
+#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Enable the specified UART interrupt.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __INTERRUPT__ specifies the UART interrupt source to enable.
+ * This parameter can be one of the following values:
+ * @arg UART_IT_CTS: CTS change interrupt
+ * @arg UART_IT_LBD: LIN Break detection interrupt
+ * @arg UART_IT_TXE: Transmit Data Register empty interrupt
+ * @arg UART_IT_TC: Transmission complete interrupt
+ * @arg UART_IT_RXNE: Receive Data register not empty interrupt
+ * @arg UART_IT_IDLE: Idle line detection interrupt
+ * @arg UART_IT_PE: Parity Error interrupt
+ * @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
+ * @retval None
+ */
+#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \
+ (((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & UART_IT_MASK)): \
+ ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)))
+
+/** @brief Disable the specified UART interrupt.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __INTERRUPT__ specifies the UART interrupt source to disable.
+ * This parameter can be one of the following values:
+ * @arg UART_IT_CTS: CTS change interrupt
+ * @arg UART_IT_LBD: LIN Break detection interrupt
+ * @arg UART_IT_TXE: Transmit Data Register empty interrupt
+ * @arg UART_IT_TC: Transmission complete interrupt
+ * @arg UART_IT_RXNE: Receive Data register not empty interrupt
+ * @arg UART_IT_IDLE: Idle line detection interrupt
+ * @arg UART_IT_PE: Parity Error interrupt
+ * @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
+ * @retval None
+ */
+#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
+ (((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
+ ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & UART_IT_MASK)))
+
+/** @brief Checks whether the specified UART interrupt source is enabled or not.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __IT__ specifies the UART interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg UART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
+ * @arg UART_IT_LBD: LIN Break detection interrupt
+ * @arg UART_IT_TXE: Transmit Data Register empty interrupt
+ * @arg UART_IT_TC: Transmission complete interrupt
+ * @arg UART_IT_RXNE: Receive Data register not empty interrupt
+ * @arg UART_IT_IDLE: Idle line detection interrupt
+ * @arg UART_IT_ERR: Error interrupt
+ * @retval The new state of __IT__ (TRUE or FALSE).
+ */
+#define __HAL_UART_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28U) == UART_CR1_REG_INDEX)? (__HANDLE__)->Instance->CR1:(((((uint32_t)(__IT__)) >> 28U) == UART_CR2_REG_INDEX)? \
+ (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & (((uint32_t)(__IT__)) & UART_IT_MASK))
+
+/** @brief Enable CTS flow control
+ * @note This macro allows to enable CTS hardware flow control for a given UART instance,
+ * without need to call HAL_UART_Init() function.
+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+ * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need
+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+ * - UART instance should have already been initialised (through call of HAL_UART_Init() )
+ * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
+ * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
+ * @param __HANDLE__ specifies the UART Handle.
+ * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
+ * It is used to select the USART peripheral (USART availability and x value depending on device).
+ * @retval None
+ */
+#define __HAL_UART_HWCONTROL_CTS_ENABLE(__HANDLE__) \
+ do{ \
+ ATOMIC_SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \
+ (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_CTSE; \
+ } while(0U)
+
+/** @brief Disable CTS flow control
+ * @note This macro allows to disable CTS hardware flow control for a given UART instance,
+ * without need to call HAL_UART_Init() function.
+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+ * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need
+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+ * - UART instance should have already been initialised (through call of HAL_UART_Init() )
+ * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
+ * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
+ * @param __HANDLE__ specifies the UART Handle.
+ * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
+ * It is used to select the USART peripheral (USART availability and x value depending on device).
+ * @retval None
+ */
+#define __HAL_UART_HWCONTROL_CTS_DISABLE(__HANDLE__) \
+ do{ \
+ ATOMIC_CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \
+ (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_CTSE); \
+ } while(0U)
+
+/** @brief Enable RTS flow control
+ * This macro allows to enable RTS hardware flow control for a given UART instance,
+ * without need to call HAL_UART_Init() function.
+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+ * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need
+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+ * - UART instance should have already been initialised (through call of HAL_UART_Init() )
+ * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
+ * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
+ * @param __HANDLE__ specifies the UART Handle.
+ * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
+ * It is used to select the USART peripheral (USART availability and x value depending on device).
+ * @retval None
+ */
+#define __HAL_UART_HWCONTROL_RTS_ENABLE(__HANDLE__) \
+ do{ \
+ ATOMIC_SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE); \
+ (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_RTSE; \
+ } while(0U)
+
+/** @brief Disable RTS flow control
+ * This macro allows to disable RTS hardware flow control for a given UART instance,
+ * without need to call HAL_UART_Init() function.
+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+ * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need
+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+ * - UART instance should have already been initialised (through call of HAL_UART_Init() )
+ * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
+ * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
+ * @param __HANDLE__ specifies the UART Handle.
+ * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
+ * It is used to select the USART peripheral (USART availability and x value depending on device).
+ * @retval None
+ */
+#define __HAL_UART_HWCONTROL_RTS_DISABLE(__HANDLE__) \
+ do{ \
+ ATOMIC_CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE);\
+ (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_RTSE); \
+ } while(0U)
+
+/** @brief Macro to enable the UART's one bit sample method
+ * @param __HANDLE__ specifies the UART Handle.
+ * @retval None
+ */
+#define __HAL_UART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT)
+
+/** @brief Macro to disable the UART's one bit sample method
+ * @param __HANDLE__ specifies the UART Handle.
+ * @retval None
+ */
+#define __HAL_UART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3\
+ &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT))
+
+/** @brief Enable UART
+ * @param __HANDLE__ specifies the UART Handle.
+ * @retval None
+ */
+#define __HAL_UART_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE)
+
+/** @brief Disable UART
+ * @param __HANDLE__ specifies the UART Handle.
+ * @retval None
+ */
+#define __HAL_UART_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE)
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup UART_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength);
+HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod);
+HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart);
+void HAL_UART_MspInit(UART_HandleTypeDef *huart);
+void HAL_UART_MspDeInit(UART_HandleTypeDef *huart);
+
+/* Callbacks Register/UnRegister functions ***********************************/
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
+ pUART_CallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID);
+
+HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/** @addtogroup UART_Exported_Functions_Group2 IO operation functions
+ * @{
+ */
+
+/* IO operation functions *******************************************************/
+HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart);
+
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
+ uint32_t Timeout);
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+
+HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(UART_HandleTypeDef *huart);
+
+/* Transfer Abort functions */
+HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart);
+
+void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);
+void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
+void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart);
+
+void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size);
+
+/**
+ * @}
+ */
+
+/** @addtogroup UART_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral Control functions ************************************************/
+HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart);
+/**
+ * @}
+ */
+
+/** @addtogroup UART_Exported_Functions_Group4
+ * @{
+ */
+/* Peripheral State functions **************************************************/
+HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart);
+uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup UART_Private_Constants UART Private Constants
+ * @{
+ */
+/** @brief UART interruptions flag mask
+ *
+ */
+#define UART_IT_MASK 0x0000FFFFU
+
+#define UART_CR1_REG_INDEX 1U
+#define UART_CR2_REG_INDEX 2U
+#define UART_CR3_REG_INDEX 3U
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup UART_Private_Macros UART Private Macros
+ * @{
+ */
+#define IS_UART_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_8B) || \
+ ((LENGTH) == UART_WORDLENGTH_9B))
+#define IS_UART_LIN_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_8B))
+#define IS_UART_STOPBITS(STOPBITS) (((STOPBITS) == UART_STOPBITS_1) || \
+ ((STOPBITS) == UART_STOPBITS_2))
+#define IS_UART_PARITY(PARITY) (((PARITY) == UART_PARITY_NONE) || \
+ ((PARITY) == UART_PARITY_EVEN) || \
+ ((PARITY) == UART_PARITY_ODD))
+#define IS_UART_HARDWARE_FLOW_CONTROL(CONTROL)\
+ (((CONTROL) == UART_HWCONTROL_NONE) || \
+ ((CONTROL) == UART_HWCONTROL_RTS) || \
+ ((CONTROL) == UART_HWCONTROL_CTS) || \
+ ((CONTROL) == UART_HWCONTROL_RTS_CTS))
+#define IS_UART_MODE(MODE) ((((MODE) & 0x0000FFF3U) == 0x00U) && ((MODE) != 0x00U))
+#define IS_UART_STATE(STATE) (((STATE) == UART_STATE_DISABLE) || \
+ ((STATE) == UART_STATE_ENABLE))
+#define IS_UART_OVERSAMPLING(SAMPLING) (((SAMPLING) == UART_OVERSAMPLING_16) || \
+ ((SAMPLING) == UART_OVERSAMPLING_8))
+#define IS_UART_LIN_OVERSAMPLING(SAMPLING) (((SAMPLING) == UART_OVERSAMPLING_16))
+#define IS_UART_LIN_BREAK_DETECT_LENGTH(LENGTH) (((LENGTH) == UART_LINBREAKDETECTLENGTH_10B) || \
+ ((LENGTH) == UART_LINBREAKDETECTLENGTH_11B))
+#define IS_UART_WAKEUPMETHOD(WAKEUP) (((WAKEUP) == UART_WAKEUPMETHOD_IDLELINE) || \
+ ((WAKEUP) == UART_WAKEUPMETHOD_ADDRESSMARK))
+#define IS_UART_BAUDRATE(BAUDRATE) ((BAUDRATE) <= 10500000U)
+#define IS_UART_ADDRESS(ADDRESS) ((ADDRESS) <= 0x0FU)
+
+#define UART_DIV_SAMPLING16(_PCLK_, _BAUD_) ((uint32_t)((((uint64_t)(_PCLK_))*25U)/(4U*((uint64_t)(_BAUD_)))))
+#define UART_DIVMANT_SAMPLING16(_PCLK_, _BAUD_) (UART_DIV_SAMPLING16((_PCLK_), (_BAUD_))/100U)
+#define UART_DIVFRAQ_SAMPLING16(_PCLK_, _BAUD_) ((((UART_DIV_SAMPLING16((_PCLK_), (_BAUD_)) - (UART_DIVMANT_SAMPLING16((_PCLK_), (_BAUD_)) * 100U)) * 16U)\
+ + 50U) / 100U)
+/* UART BRR = mantissa + overflow + fraction
+ = (UART DIVMANT << 4) + (UART DIVFRAQ & 0xF0) + (UART DIVFRAQ & 0x0FU) */
+#define UART_BRR_SAMPLING16(_PCLK_, _BAUD_) ((UART_DIVMANT_SAMPLING16((_PCLK_), (_BAUD_)) << 4U) + \
+ (UART_DIVFRAQ_SAMPLING16((_PCLK_), (_BAUD_)) & 0xF0U) + \
+ (UART_DIVFRAQ_SAMPLING16((_PCLK_), (_BAUD_)) & 0x0FU))
+
+#define UART_DIV_SAMPLING8(_PCLK_, _BAUD_) ((uint32_t)((((uint64_t)(_PCLK_))*25U)/(2U*((uint64_t)(_BAUD_)))))
+#define UART_DIVMANT_SAMPLING8(_PCLK_, _BAUD_) (UART_DIV_SAMPLING8((_PCLK_), (_BAUD_))/100U)
+#define UART_DIVFRAQ_SAMPLING8(_PCLK_, _BAUD_) ((((UART_DIV_SAMPLING8((_PCLK_), (_BAUD_)) - (UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) * 100U)) * 8U)\
+ + 50U) / 100U)
+/* UART BRR = mantissa + overflow + fraction
+ = (UART DIVMANT << 4) + ((UART DIVFRAQ & 0xF8) << 1) + (UART DIVFRAQ & 0x07U) */
+#define UART_BRR_SAMPLING8(_PCLK_, _BAUD_) ((UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) << 4U) + \
+ ((UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) & 0xF8U) << 1U) + \
+ (UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) & 0x07U))
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup UART_Private_Functions UART Private Functions
+ * @{
+ */
+
+HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_HAL_UART_H */
+
diff --git a/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_fsmc.h b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_fsmc.h
new file mode 100644
index 0000000..ebfee75
--- /dev/null
+++ b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_fsmc.h
@@ -0,0 +1,1093 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_ll_fsmc.h
+ * @author MCD Application Team
+ * @brief Header file of FSMC HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32F4xx_LL_FSMC_H
+#define STM32F4xx_LL_FSMC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal_def.h"
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup FSMC_LL
+ * @{
+ */
+
+/** @addtogroup FSMC_LL_Private_Macros
+ * @{
+ */
+#if defined(FSMC_Bank1)
+
+#define IS_FSMC_NORSRAM_BANK(__BANK__) (((__BANK__) == FSMC_NORSRAM_BANK1) || \
+ ((__BANK__) == FSMC_NORSRAM_BANK2) || \
+ ((__BANK__) == FSMC_NORSRAM_BANK3) || \
+ ((__BANK__) == FSMC_NORSRAM_BANK4))
+#define IS_FSMC_MUX(__MUX__) (((__MUX__) == FSMC_DATA_ADDRESS_MUX_DISABLE) || \
+ ((__MUX__) == FSMC_DATA_ADDRESS_MUX_ENABLE))
+#define IS_FSMC_MEMORY(__MEMORY__) (((__MEMORY__) == FSMC_MEMORY_TYPE_SRAM) || \
+ ((__MEMORY__) == FSMC_MEMORY_TYPE_PSRAM)|| \
+ ((__MEMORY__) == FSMC_MEMORY_TYPE_NOR))
+#define IS_FSMC_NORSRAM_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_8) || \
+ ((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_16) || \
+ ((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_32))
+#define IS_FSMC_PAGESIZE(__SIZE__) (((__SIZE__) == FSMC_PAGE_SIZE_NONE) || \
+ ((__SIZE__) == FSMC_PAGE_SIZE_128) || \
+ ((__SIZE__) == FSMC_PAGE_SIZE_256) || \
+ ((__SIZE__) == FSMC_PAGE_SIZE_512) || \
+ ((__SIZE__) == FSMC_PAGE_SIZE_1024))
+#if defined(FSMC_BCR1_WFDIS)
+#define IS_FSMC_WRITE_FIFO(__FIFO__) (((__FIFO__) == FSMC_WRITE_FIFO_DISABLE) || \
+ ((__FIFO__) == FSMC_WRITE_FIFO_ENABLE))
+#endif /* FSMC_BCR1_WFDIS */
+#define IS_FSMC_ACCESS_MODE(__MODE__) (((__MODE__) == FSMC_ACCESS_MODE_A) || \
+ ((__MODE__) == FSMC_ACCESS_MODE_B) || \
+ ((__MODE__) == FSMC_ACCESS_MODE_C) || \
+ ((__MODE__) == FSMC_ACCESS_MODE_D))
+#define IS_FSMC_BURSTMODE(__STATE__) (((__STATE__) == FSMC_BURST_ACCESS_MODE_DISABLE) || \
+ ((__STATE__) == FSMC_BURST_ACCESS_MODE_ENABLE))
+#define IS_FSMC_WAIT_POLARITY(__POLARITY__) (((__POLARITY__) == FSMC_WAIT_SIGNAL_POLARITY_LOW) || \
+ ((__POLARITY__) == FSMC_WAIT_SIGNAL_POLARITY_HIGH))
+#define IS_FSMC_WRAP_MODE(__MODE__) (((__MODE__) == FSMC_WRAP_MODE_DISABLE) || \
+ ((__MODE__) == FSMC_WRAP_MODE_ENABLE))
+#define IS_FSMC_WAIT_SIGNAL_ACTIVE(__ACTIVE__) (((__ACTIVE__) == FSMC_WAIT_TIMING_BEFORE_WS) || \
+ ((__ACTIVE__) == FSMC_WAIT_TIMING_DURING_WS))
+#define IS_FSMC_WRITE_OPERATION(__OPERATION__) (((__OPERATION__) == FSMC_WRITE_OPERATION_DISABLE) || \
+ ((__OPERATION__) == FSMC_WRITE_OPERATION_ENABLE))
+#define IS_FSMC_WAITE_SIGNAL(__SIGNAL__) (((__SIGNAL__) == FSMC_WAIT_SIGNAL_DISABLE) || \
+ ((__SIGNAL__) == FSMC_WAIT_SIGNAL_ENABLE))
+#define IS_FSMC_EXTENDED_MODE(__MODE__) (((__MODE__) == FSMC_EXTENDED_MODE_DISABLE) || \
+ ((__MODE__) == FSMC_EXTENDED_MODE_ENABLE))
+#define IS_FSMC_ASYNWAIT(__STATE__) (((__STATE__) == FSMC_ASYNCHRONOUS_WAIT_DISABLE) || \
+ ((__STATE__) == FSMC_ASYNCHRONOUS_WAIT_ENABLE))
+#define IS_FSMC_DATA_LATENCY(__LATENCY__) (((__LATENCY__) > 1U) && ((__LATENCY__) <= 17U))
+#define IS_FSMC_WRITE_BURST(__BURST__) (((__BURST__) == FSMC_WRITE_BURST_DISABLE) || \
+ ((__BURST__) == FSMC_WRITE_BURST_ENABLE))
+#define IS_FSMC_CONTINOUS_CLOCK(__CCLOCK__) (((__CCLOCK__) == FSMC_CONTINUOUS_CLOCK_SYNC_ONLY) || \
+ ((__CCLOCK__) == FSMC_CONTINUOUS_CLOCK_SYNC_ASYNC))
+#define IS_FSMC_ADDRESS_SETUP_TIME(__TIME__) ((__TIME__) <= 15U)
+#define IS_FSMC_ADDRESS_HOLD_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 15U))
+#define IS_FSMC_DATASETUP_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 255U))
+#define IS_FSMC_DATAHOLD_DURATION(__DATAHOLD__) ((__DATAHOLD__) <= 3U)
+#define IS_FSMC_TURNAROUND_TIME(__TIME__) ((__TIME__) <= 15U)
+#define IS_FSMC_CLK_DIV(__DIV__) (((__DIV__) > 1U) && ((__DIV__) <= 16U))
+#define IS_FSMC_NORSRAM_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NORSRAM_DEVICE)
+#define IS_FSMC_NORSRAM_EXTENDED_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NORSRAM_EXTENDED_DEVICE)
+
+#endif /* FSMC_Bank1 */
+#if defined(FSMC_Bank2_3)
+
+#define IS_FSMC_NAND_BANK(__BANK__) (((__BANK__) == FSMC_NAND_BANK2) || \
+ ((__BANK__) == FSMC_NAND_BANK3))
+#define IS_FSMC_WAIT_FEATURE(__FEATURE__) (((__FEATURE__) == FSMC_NAND_PCC_WAIT_FEATURE_DISABLE) || \
+ ((__FEATURE__) == FSMC_NAND_PCC_WAIT_FEATURE_ENABLE))
+#define IS_FSMC_NAND_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FSMC_NAND_PCC_MEM_BUS_WIDTH_8) || \
+ ((__WIDTH__) == FSMC_NAND_PCC_MEM_BUS_WIDTH_16))
+#define IS_FSMC_ECC_STATE(__STATE__) (((__STATE__) == FSMC_NAND_ECC_DISABLE) || \
+ ((__STATE__) == FSMC_NAND_ECC_ENABLE))
+
+#define IS_FSMC_ECCPAGE_SIZE(__SIZE__) (((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_256BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_512BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_1024BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_2048BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_4096BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_8192BYTE))
+#define IS_FSMC_TCLR_TIME(__TIME__) ((__TIME__) <= 255U)
+#define IS_FSMC_TAR_TIME(__TIME__) ((__TIME__) <= 255U)
+#define IS_FSMC_SETUP_TIME(__TIME__) ((__TIME__) <= 254U)
+#define IS_FSMC_WAIT_TIME(__TIME__) ((__TIME__) <= 254U)
+#define IS_FSMC_HOLD_TIME(__TIME__) ((__TIME__) <= 254U)
+#define IS_FSMC_HIZ_TIME(__TIME__) ((__TIME__) <= 254U)
+#define IS_FSMC_NAND_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NAND_DEVICE)
+
+#endif /* FSMC_Bank2_3 */
+#if defined(FSMC_Bank4)
+#define IS_FSMC_PCCARD_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_PCCARD_DEVICE)
+
+#endif /* FSMC_Bank4 */
+
+/**
+ * @}
+ */
+
+/* Exported typedef ----------------------------------------------------------*/
+
+/** @defgroup FSMC_LL_Exported_typedef FSMC Low Layer Exported Types
+ * @{
+ */
+
+#if defined(FSMC_Bank1)
+#define FSMC_NORSRAM_TypeDef FSMC_Bank1_TypeDef
+#define FSMC_NORSRAM_EXTENDED_TypeDef FSMC_Bank1E_TypeDef
+#endif /* FSMC_Bank1 */
+#if defined(FSMC_Bank2_3)
+#define FSMC_NAND_TypeDef FSMC_Bank2_3_TypeDef
+#endif /* FSMC_Bank2_3 */
+#if defined(FSMC_Bank4)
+#define FSMC_PCCARD_TypeDef FSMC_Bank4_TypeDef
+#endif /* FSMC_Bank4 */
+
+#if defined(FSMC_Bank1)
+#define FSMC_NORSRAM_DEVICE FSMC_Bank1
+#define FSMC_NORSRAM_EXTENDED_DEVICE FSMC_Bank1E
+#endif /* FSMC_Bank1 */
+#if defined(FSMC_Bank2_3)
+#define FSMC_NAND_DEVICE FSMC_Bank2_3
+#endif /* FSMC_Bank2_3 */
+#if defined(FSMC_Bank4)
+#define FSMC_PCCARD_DEVICE FSMC_Bank4
+#endif /* FSMC_Bank4 */
+
+#if defined(FSMC_Bank1)
+/**
+ * @brief FSMC NORSRAM Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t NSBank; /*!< Specifies the NORSRAM memory device that will be used.
+ This parameter can be a value of @ref FSMC_NORSRAM_Bank */
+
+ uint32_t DataAddressMux; /*!< Specifies whether the address and data values are
+ multiplexed on the data bus or not.
+ This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing*/
+
+ uint32_t MemoryType; /*!< Specifies the type of external memory attached to
+ the corresponding memory device.
+ This parameter can be a value of @ref FSMC_Memory_Type */
+
+ uint32_t MemoryDataWidth; /*!< Specifies the external memory device width.
+ This parameter can be a value of @ref FSMC_NORSRAM_Data_Width */
+
+ uint32_t BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory,
+ valid only with synchronous burst Flash memories.
+ This parameter can be a value of @ref FSMC_Burst_Access_Mode */
+
+ uint32_t WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing
+ the Flash memory in burst mode.
+ This parameter can be a value of @ref FSMC_Wait_Signal_Polarity */
+
+ uint32_t WrapMode; /*!< Enables or disables the Wrapped burst access mode for Flash
+ memory, valid only when accessing Flash memories in burst mode.
+ This parameter can be a value of @ref FSMC_Wrap_Mode
+ This mode is available only for the STM32F405/407/4015/417xx devices */
+
+ uint32_t WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one
+ clock cycle before the wait state or during the wait state,
+ valid only when accessing memories in burst mode.
+ This parameter can be a value of @ref FSMC_Wait_Timing */
+
+ uint32_t WriteOperation; /*!< Enables or disables the write operation in the selected device
+ by the FSMC.
+ This parameter can be a value of @ref FSMC_Write_Operation */
+
+ uint32_t WaitSignal; /*!< Enables or disables the wait state insertion via wait
+ signal, valid for Flash memory access in burst mode.
+ This parameter can be a value of @ref FSMC_Wait_Signal */
+
+ uint32_t ExtendedMode; /*!< Enables or disables the extended mode.
+ This parameter can be a value of @ref FSMC_Extended_Mode */
+
+ uint32_t AsynchronousWait; /*!< Enables or disables wait signal during asynchronous transfers,
+ valid only with asynchronous Flash memories.
+ This parameter can be a value of @ref FSMC_AsynchronousWait */
+
+ uint32_t WriteBurst; /*!< Enables or disables the write burst operation.
+ This parameter can be a value of @ref FSMC_Write_Burst */
+
+ uint32_t ContinuousClock; /*!< Enables or disables the FSMC clock output to external memory devices.
+ This parameter is only enabled through the FSMC_BCR1 register,
+ and don't care through FSMC_BCR2..4 registers.
+ This parameter can be a value of @ref FSMC_Continous_Clock
+ This mode is available only for the STM32F412Vx/Zx/Rx devices */
+
+ uint32_t WriteFifo; /*!< Enables or disables the write FIFO used by the FSMC controller.
+ This parameter is only enabled through the FSMC_BCR1 register,
+ and don't care through FSMC_BCR2..4 registers.
+ This parameter can be a value of @ref FSMC_Write_FIFO
+ This mode is available only for the STM32F412Vx/Vx devices */
+
+ uint32_t PageSize; /*!< Specifies the memory page size.
+ This parameter can be a value of @ref FSMC_Page_Size */
+} FSMC_NORSRAM_InitTypeDef;
+
+/**
+ * @brief FSMC NORSRAM Timing parameters structure definition
+ */
+typedef struct
+{
+ uint32_t AddressSetupTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the address setup time.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 15.
+ @note This parameter is not used with synchronous NOR Flash memories. */
+
+ uint32_t AddressHoldTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the address hold time.
+ This parameter can be a value between Min_Data = 1 and Max_Data = 15.
+ @note This parameter is not used with synchronous NOR Flash memories. */
+
+ uint32_t DataSetupTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the data setup time.
+ This parameter can be a value between Min_Data = 1 and Max_Data = 255.
+ @note This parameter is used for SRAMs, ROMs and asynchronous multiplexed
+ NOR Flash memories. */
+
+ uint32_t BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure
+ the duration of the bus turnaround.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 15.
+ @note This parameter is only used for multiplexed NOR Flash memories. */
+
+ uint32_t CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of
+ HCLK cycles. This parameter can be a value between Min_Data = 2 and
+ Max_Data = 16.
+ @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM
+ accesses. */
+
+ uint32_t DataLatency; /*!< Defines the number of memory clock cycles to issue
+ to the memory before getting the first data.
+ The parameter value depends on the memory type as shown below:
+ - It must be set to 0 in case of a CRAM
+ - It is don't care in asynchronous NOR, SRAM or ROM accesses
+ - It may assume a value between Min_Data = 2 and Max_Data = 17
+ in NOR Flash memories with synchronous burst mode enable */
+
+ uint32_t AccessMode; /*!< Specifies the asynchronous access mode.
+ This parameter can be a value of @ref FSMC_Access_Mode */
+} FSMC_NORSRAM_TimingTypeDef;
+#endif /* FSMC_Bank1 */
+
+#if defined(FSMC_Bank2_3)
+/**
+ * @brief FSMC NAND Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t NandBank; /*!< Specifies the NAND memory device that will be used.
+ This parameter can be a value of @ref FSMC_NAND_Bank */
+
+ uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory device.
+ This parameter can be any value of @ref FSMC_Wait_feature */
+
+ uint32_t MemoryDataWidth; /*!< Specifies the external memory device width.
+ This parameter can be any value of @ref FSMC_NAND_Data_Width */
+
+ uint32_t EccComputation; /*!< Enables or disables the ECC computation.
+ This parameter can be any value of @ref FSMC_ECC */
+
+ uint32_t ECCPageSize; /*!< Defines the page size for the extended ECC.
+ This parameter can be any value of @ref FSMC_ECC_Page_Size */
+
+ uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between CLE low and RE low.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 255 */
+
+ uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between ALE low and RE low.
+ This parameter can be a number between Min_Data = 0 and Max_Data = 255 */
+} FSMC_NAND_InitTypeDef;
+#endif /* FSMC_Bank2_3 */
+
+#if defined(FSMC_Bank2_3) || defined(FSMC_Bank4)
+/**
+ * @brief FSMC NAND Timing parameters structure definition
+ */
+typedef struct
+{
+ uint32_t SetupTime; /*!< Defines the number of HCLK cycles to setup address before
+ the command assertion for NAND-Flash read or write access
+ to common/Attribute or I/O memory space (depending on
+ the memory space timing to be configured).
+ This parameter can be a value between Min_Data = 0 and Max_Data = 254 */
+
+ uint32_t WaitSetupTime; /*!< Defines the minimum number of HCLK cycles to assert the
+ command for NAND-Flash read or write access to
+ common/Attribute or I/O memory space (depending on the
+ memory space timing to be configured).
+ This parameter can be a number between Min_Data = 0 and Max_Data = 254 */
+
+ uint32_t HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address
+ (and data for write access) after the command de-assertion
+ for NAND-Flash read or write access to common/Attribute
+ or I/O memory space (depending on the memory space timing
+ to be configured).
+ This parameter can be a number between Min_Data = 0 and Max_Data = 254 */
+
+ uint32_t HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the
+ data bus is kept in HiZ after the start of a NAND-Flash
+ write access to common/Attribute or I/O memory space (depending
+ on the memory space timing to be configured).
+ This parameter can be a number between Min_Data = 0 and Max_Data = 254 */
+} FSMC_NAND_PCC_TimingTypeDef;
+#endif /* FSMC_Bank2_3 */
+
+#if defined(FSMC_Bank4)
+/**
+ * @brief FSMC PCCARD Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the PCCARD Memory device.
+ This parameter can be any value of @ref FSMC_Wait_feature */
+
+ uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between CLE low and RE low.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 255 */
+
+ uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between ALE low and RE low.
+ This parameter can be a number between Min_Data = 0 and Max_Data = 255 */
+} FSMC_PCCARD_InitTypeDef;
+#endif /* FSMC_Bank4 */
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @addtogroup FSMC_LL_Exported_Constants FSMC Low Layer Exported Constants
+ * @{
+ */
+#if defined(FSMC_Bank1)
+
+/** @defgroup FSMC_LL_NOR_SRAM_Controller FSMC NOR/SRAM Controller
+ * @{
+ */
+
+/** @defgroup FSMC_NORSRAM_Bank FSMC NOR/SRAM Bank
+ * @{
+ */
+#define FSMC_NORSRAM_BANK1 (0x00000000U)
+#define FSMC_NORSRAM_BANK2 (0x00000002U)
+#define FSMC_NORSRAM_BANK3 (0x00000004U)
+#define FSMC_NORSRAM_BANK4 (0x00000006U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Data_Address_Bus_Multiplexing FSMC Data Address Bus Multiplexing
+ * @{
+ */
+#define FSMC_DATA_ADDRESS_MUX_DISABLE (0x00000000U)
+#define FSMC_DATA_ADDRESS_MUX_ENABLE (0x00000002U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Memory_Type FSMC Memory Type
+ * @{
+ */
+#define FSMC_MEMORY_TYPE_SRAM (0x00000000U)
+#define FSMC_MEMORY_TYPE_PSRAM (0x00000004U)
+#define FSMC_MEMORY_TYPE_NOR (0x00000008U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NORSRAM_Data_Width FSMC NORSRAM Data Width
+ * @{
+ */
+#define FSMC_NORSRAM_MEM_BUS_WIDTH_8 (0x00000000U)
+#define FSMC_NORSRAM_MEM_BUS_WIDTH_16 (0x00000010U)
+#define FSMC_NORSRAM_MEM_BUS_WIDTH_32 (0x00000020U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NORSRAM_Flash_Access FSMC NOR/SRAM Flash Access
+ * @{
+ */
+#define FSMC_NORSRAM_FLASH_ACCESS_ENABLE (0x00000040U)
+#define FSMC_NORSRAM_FLASH_ACCESS_DISABLE (0x00000000U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Burst_Access_Mode FSMC Burst Access Mode
+ * @{
+ */
+#define FSMC_BURST_ACCESS_MODE_DISABLE (0x00000000U)
+#define FSMC_BURST_ACCESS_MODE_ENABLE (0x00000100U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Signal_Polarity FSMC Wait Signal Polarity
+ * @{
+ */
+#define FSMC_WAIT_SIGNAL_POLARITY_LOW (0x00000000U)
+#define FSMC_WAIT_SIGNAL_POLARITY_HIGH (0x00000200U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wrap_Mode FSMC Wrap Mode
+ * @note These values are available only for the STM32F405/415/407/417xx devices.
+ * @{
+ */
+#define FSMC_WRAP_MODE_DISABLE (0x00000000U)
+#define FSMC_WRAP_MODE_ENABLE (0x00000400U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Timing FSMC Wait Timing
+ * @{
+ */
+#define FSMC_WAIT_TIMING_BEFORE_WS (0x00000000U)
+#define FSMC_WAIT_TIMING_DURING_WS (0x00000800U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Write_Operation FSMC Write Operation
+ * @{
+ */
+#define FSMC_WRITE_OPERATION_DISABLE (0x00000000U)
+#define FSMC_WRITE_OPERATION_ENABLE (0x00001000U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Signal FSMC Wait Signal
+ * @{
+ */
+#define FSMC_WAIT_SIGNAL_DISABLE (0x00000000U)
+#define FSMC_WAIT_SIGNAL_ENABLE (0x00002000U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Extended_Mode FSMC Extended Mode
+ * @{
+ */
+#define FSMC_EXTENDED_MODE_DISABLE (0x00000000U)
+#define FSMC_EXTENDED_MODE_ENABLE (0x00004000U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_AsynchronousWait FSMC Asynchronous Wait
+ * @{
+ */
+#define FSMC_ASYNCHRONOUS_WAIT_DISABLE (0x00000000U)
+#define FSMC_ASYNCHRONOUS_WAIT_ENABLE (0x00008000U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Page_Size FSMC Page Size
+ * @{
+ */
+#define FSMC_PAGE_SIZE_NONE (0x00000000U)
+#define FSMC_PAGE_SIZE_128 FSMC_BCR1_CPSIZE_0
+#define FSMC_PAGE_SIZE_256 FSMC_BCR1_CPSIZE_1
+#define FSMC_PAGE_SIZE_512 (FSMC_BCR1_CPSIZE_0\
+ | FSMC_BCR1_CPSIZE_1)
+#define FSMC_PAGE_SIZE_1024 FSMC_BCR1_CPSIZE_2
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Write_Burst FSMC Write Burst
+ * @{
+ */
+#define FSMC_WRITE_BURST_DISABLE (0x00000000U)
+#define FSMC_WRITE_BURST_ENABLE (0x00080000U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Continous_Clock FSMC Continuous Clock
+ * @note These values are available only for the STM32F412Vx/Zx/Rx devices.
+ * @{
+ */
+#define FSMC_CONTINUOUS_CLOCK_SYNC_ONLY (0x00000000U)
+#define FSMC_CONTINUOUS_CLOCK_SYNC_ASYNC (0x00100000U)
+/**
+ * @}
+ */
+
+#if defined(FSMC_BCR1_WFDIS)
+/** @defgroup FSMC_Write_FIFO FSMC Write FIFO
+ * @note These values are available only for the STM32F412Vx/Zx/Rx devices.
+ * @{
+ */
+#define FSMC_WRITE_FIFO_DISABLE FSMC_BCR1_WFDIS
+#define FSMC_WRITE_FIFO_ENABLE (0x00000000U)
+#endif /* FSMC_BCR1_WFDIS */
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Access_Mode FSMC Access Mode
+ * @{
+ */
+#define FSMC_ACCESS_MODE_A (0x00000000U)
+#define FSMC_ACCESS_MODE_B (0x10000000U)
+#define FSMC_ACCESS_MODE_C (0x20000000U)
+#define FSMC_ACCESS_MODE_D (0x30000000U)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* FSMC_Bank1 */
+
+#if defined(FSMC_Bank2_3) || defined(FSMC_Bank4)
+
+/** @defgroup FSMC_LL_NAND_Controller FSMC NAND Controller
+ * @{
+ */
+/** @defgroup FSMC_NAND_Bank FSMC NAND Bank
+ * @{
+ */
+#if defined(FSMC_Bank2_3)
+#define FSMC_NAND_BANK2 (0x00000010U)
+#endif /* FSMC_Bank2_3 */
+#define FSMC_NAND_BANK3 (0x00000100U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_feature FSMC Wait feature
+ * @{
+ */
+#define FSMC_NAND_PCC_WAIT_FEATURE_DISABLE (0x00000000U)
+#define FSMC_NAND_PCC_WAIT_FEATURE_ENABLE (0x00000002U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_PCR_Memory_Type FSMC PCR Memory Type
+ * @{
+ */
+#if defined(FSMC_Bank4)
+#define FSMC_PCR_MEMORY_TYPE_PCCARD (0x00000000U)
+#endif /* FSMC_Bank4 */
+#define FSMC_PCR_MEMORY_TYPE_NAND (0x00000008U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NAND_Data_Width FSMC NAND Data Width
+ * @{
+ */
+#define FSMC_NAND_PCC_MEM_BUS_WIDTH_8 (0x00000000U)
+#define FSMC_NAND_PCC_MEM_BUS_WIDTH_16 (0x00000010U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_ECC FSMC ECC
+ * @{
+ */
+#define FSMC_NAND_ECC_DISABLE (0x00000000U)
+#define FSMC_NAND_ECC_ENABLE (0x00000040U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_ECC_Page_Size FSMC ECC Page Size
+ * @{
+ */
+#define FSMC_NAND_ECC_PAGE_SIZE_256BYTE (0x00000000U)
+#define FSMC_NAND_ECC_PAGE_SIZE_512BYTE (0x00020000U)
+#define FSMC_NAND_ECC_PAGE_SIZE_1024BYTE (0x00040000U)
+#define FSMC_NAND_ECC_PAGE_SIZE_2048BYTE (0x00060000U)
+#define FSMC_NAND_ECC_PAGE_SIZE_4096BYTE (0x00080000U)
+#define FSMC_NAND_ECC_PAGE_SIZE_8192BYTE (0x000A0000U)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* FSMC_Bank2_3 || FSMC_Bank4 */
+
+
+/** @defgroup FSMC_LL_Interrupt_definition FSMC Low Layer Interrupt definition
+ * @{
+ */
+#if defined(FSMC_Bank2_3) || defined(FSMC_Bank4)
+#define FSMC_IT_RISING_EDGE (0x00000008U)
+#define FSMC_IT_LEVEL (0x00000010U)
+#define FSMC_IT_FALLING_EDGE (0x00000020U)
+#endif /* FSMC_Bank2_3 || FSMC_Bank4 */
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_LL_Flag_definition FSMC Low Layer Flag definition
+ * @{
+ */
+#if defined(FSMC_Bank2_3) || defined(FSMC_Bank4)
+#define FSMC_FLAG_RISING_EDGE (0x00000001U)
+#define FSMC_FLAG_LEVEL (0x00000002U)
+#define FSMC_FLAG_FALLING_EDGE (0x00000004U)
+#define FSMC_FLAG_FEMPT (0x00000040U)
+#endif /* FSMC_Bank2_3 || FSMC_Bank4 */
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_LL_Alias_definition FSMC Alias definition
+ * @{
+ */
+#define FMC_WRITE_OPERATION_DISABLE FSMC_WRITE_OPERATION_DISABLE
+#define FMC_WRITE_OPERATION_ENABLE FSMC_WRITE_OPERATION_ENABLE
+
+#define FMC_NORSRAM_MEM_BUS_WIDTH_8 FSMC_NORSRAM_MEM_BUS_WIDTH_8
+#define FMC_NORSRAM_MEM_BUS_WIDTH_16 FSMC_NORSRAM_MEM_BUS_WIDTH_16
+#define FMC_NORSRAM_MEM_BUS_WIDTH_32 FSMC_NORSRAM_MEM_BUS_WIDTH_32
+
+#define FMC_NORSRAM_TypeDef FSMC_NORSRAM_TypeDef
+#define FMC_NORSRAM_EXTENDED_TypeDef FSMC_NORSRAM_EXTENDED_TypeDef
+#define FMC_NORSRAM_InitTypeDef FSMC_NORSRAM_InitTypeDef
+#define FMC_NORSRAM_TimingTypeDef FSMC_NORSRAM_TimingTypeDef
+
+#define FMC_NORSRAM_Init FSMC_NORSRAM_Init
+#define FMC_NORSRAM_Timing_Init FSMC_NORSRAM_Timing_Init
+#define FMC_NORSRAM_Extended_Timing_Init FSMC_NORSRAM_Extended_Timing_Init
+#define FMC_NORSRAM_DeInit FSMC_NORSRAM_DeInit
+#define FMC_NORSRAM_WriteOperation_Enable FSMC_NORSRAM_WriteOperation_Enable
+#define FMC_NORSRAM_WriteOperation_Disable FSMC_NORSRAM_WriteOperation_Disable
+
+#define __FMC_NORSRAM_ENABLE __FSMC_NORSRAM_ENABLE
+#define __FMC_NORSRAM_DISABLE __FSMC_NORSRAM_DISABLE
+
+#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
+#define FMC_NAND_InitTypeDef FSMC_NAND_InitTypeDef
+#define FMC_PCCARD_InitTypeDef FSMC_PCCARD_InitTypeDef
+#define FMC_NAND_PCC_TimingTypeDef FSMC_NAND_PCC_TimingTypeDef
+
+#define FMC_NAND_Init FSMC_NAND_Init
+#define FMC_NAND_CommonSpace_Timing_Init FSMC_NAND_CommonSpace_Timing_Init
+#define FMC_NAND_AttributeSpace_Timing_Init FSMC_NAND_AttributeSpace_Timing_Init
+#define FMC_NAND_DeInit FSMC_NAND_DeInit
+#define FMC_NAND_ECC_Enable FSMC_NAND_ECC_Enable
+#define FMC_NAND_ECC_Disable FSMC_NAND_ECC_Disable
+#define FMC_NAND_GetECC FSMC_NAND_GetECC
+#define FMC_PCCARD_Init FSMC_PCCARD_Init
+#define FMC_PCCARD_CommonSpace_Timing_Init FSMC_PCCARD_CommonSpace_Timing_Init
+#define FMC_PCCARD_AttributeSpace_Timing_Init FSMC_PCCARD_AttributeSpace_Timing_Init
+#define FMC_PCCARD_IOSpace_Timing_Init FSMC_PCCARD_IOSpace_Timing_Init
+#define FMC_PCCARD_DeInit FSMC_PCCARD_DeInit
+
+#define __FMC_NAND_ENABLE __FSMC_NAND_ENABLE
+#define __FMC_NAND_DISABLE __FSMC_NAND_DISABLE
+#define __FMC_PCCARD_ENABLE __FSMC_PCCARD_ENABLE
+#define __FMC_PCCARD_DISABLE __FSMC_PCCARD_DISABLE
+#define __FMC_NAND_ENABLE_IT __FSMC_NAND_ENABLE_IT
+#define __FMC_NAND_DISABLE_IT __FSMC_NAND_DISABLE_IT
+#define __FMC_NAND_GET_FLAG __FSMC_NAND_GET_FLAG
+#define __FMC_NAND_CLEAR_FLAG __FSMC_NAND_CLEAR_FLAG
+#define __FMC_PCCARD_ENABLE_IT __FSMC_PCCARD_ENABLE_IT
+#define __FMC_PCCARD_DISABLE_IT __FSMC_PCCARD_DISABLE_IT
+#define __FMC_PCCARD_GET_FLAG __FSMC_PCCARD_GET_FLAG
+#define __FMC_PCCARD_CLEAR_FLAG __FSMC_PCCARD_CLEAR_FLAG
+#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */
+
+#define FMC_NORSRAM_TypeDef FSMC_NORSRAM_TypeDef
+#define FMC_NORSRAM_EXTENDED_TypeDef FSMC_NORSRAM_EXTENDED_TypeDef
+#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
+#define FMC_NAND_TypeDef FSMC_NAND_TypeDef
+#define FMC_PCCARD_TypeDef FSMC_PCCARD_TypeDef
+#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */
+
+#define FMC_NORSRAM_DEVICE FSMC_NORSRAM_DEVICE
+#define FMC_NORSRAM_EXTENDED_DEVICE FSMC_NORSRAM_EXTENDED_DEVICE
+#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
+#define FMC_NAND_DEVICE FSMC_NAND_DEVICE
+#define FMC_PCCARD_DEVICE FSMC_PCCARD_DEVICE
+
+#define FMC_NAND_BANK2 FSMC_NAND_BANK2
+#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */
+
+#define FMC_NORSRAM_BANK1 FSMC_NORSRAM_BANK1
+#define FMC_NORSRAM_BANK2 FSMC_NORSRAM_BANK2
+#define FMC_NORSRAM_BANK3 FSMC_NORSRAM_BANK3
+
+#define FMC_IT_RISING_EDGE FSMC_IT_RISING_EDGE
+#define FMC_IT_LEVEL FSMC_IT_LEVEL
+#define FMC_IT_FALLING_EDGE FSMC_IT_FALLING_EDGE
+#define FMC_IT_REFRESH_ERROR FSMC_IT_REFRESH_ERROR
+
+#define FMC_FLAG_RISING_EDGE FSMC_FLAG_RISING_EDGE
+#define FMC_FLAG_LEVEL FSMC_FLAG_LEVEL
+#define FMC_FLAG_FALLING_EDGE FSMC_FLAG_FALLING_EDGE
+#define FMC_FLAG_FEMPT FSMC_FLAG_FEMPT
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/** @defgroup FSMC_LL_Private_Macros FSMC_LL Private Macros
+ * @{
+ */
+#if defined(FSMC_Bank1)
+/** @defgroup FSMC_LL_NOR_Macros FSMC NOR/SRAM Macros
+ * @brief macros to handle NOR device enable/disable and read/write operations
+ * @{
+ */
+
+/**
+ * @brief Enable the NORSRAM device access.
+ * @param __INSTANCE__ FSMC_NORSRAM Instance
+ * @param __BANK__ FSMC_NORSRAM Bank
+ * @retval None
+ */
+#define __FSMC_NORSRAM_ENABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->BTCR[(__BANK__)]\
+ |= FSMC_BCR1_MBKEN)
+
+/**
+ * @brief Disable the NORSRAM device access.
+ * @param __INSTANCE__ FSMC_NORSRAM Instance
+ * @param __BANK__ FSMC_NORSRAM Bank
+ * @retval None
+ */
+#define __FSMC_NORSRAM_DISABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->BTCR[(__BANK__)]\
+ &= ~FSMC_BCR1_MBKEN)
+
+/**
+ * @}
+ */
+#endif /* FSMC_Bank1 */
+
+#if defined(FSMC_Bank2_3)
+/** @defgroup FSMC_LL_NAND_Macros FSMC NAND Macros
+ * @brief macros to handle NAND device enable/disable
+ * @{
+ */
+
+/**
+ * @brief Enable the NAND device access.
+ * @param __INSTANCE__ FSMC_NAND Instance
+ * @param __BANK__ FSMC_NAND Bank
+ * @retval None
+ */
+#define __FSMC_NAND_ENABLE(__INSTANCE__, __BANK__) (((__BANK__) == FSMC_NAND_BANK2) ? \
+ ((__INSTANCE__)->PCR2 |= FSMC_PCR2_PBKEN) : \
+ ((__INSTANCE__)->PCR3 |= FSMC_PCR3_PBKEN))
+
+/**
+ * @brief Disable the NAND device access.
+ * @param __INSTANCE__ FSMC_NAND Instance
+ * @param __BANK__ FSMC_NAND Bank
+ * @retval None
+ */
+#define __FSMC_NAND_DISABLE(__INSTANCE__, __BANK__) (((__BANK__) == FSMC_NAND_BANK2) ? \
+ CLEAR_BIT((__INSTANCE__)->PCR2, FSMC_PCR2_PBKEN) : \
+ CLEAR_BIT((__INSTANCE__)->PCR3, FSMC_PCR3_PBKEN))
+
+/**
+ * @}
+ */
+#endif /* FSMC_Bank2_3 */
+
+#if defined(FSMC_Bank4)
+/** @defgroup FSMC_LL_PCCARD_Macros FMC PCCARD Macros
+ * @brief macros to handle PCCARD read/write operations
+ * @{
+ */
+/**
+ * @brief Enable the PCCARD device access.
+ * @param __INSTANCE__ FSMC_PCCARD Instance
+ * @retval None
+ */
+#define __FSMC_PCCARD_ENABLE(__INSTANCE__) ((__INSTANCE__)->PCR4 |= FSMC_PCR4_PBKEN)
+
+/**
+ * @brief Disable the PCCARD device access.
+ * @param __INSTANCE__ FSMC_PCCARD Instance
+ * @retval None
+ */
+#define __FSMC_PCCARD_DISABLE(__INSTANCE__) ((__INSTANCE__)->PCR4 &= ~FSMC_PCR4_PBKEN)
+/**
+ * @}
+ */
+
+#endif /* FSMC_Bank4 */
+#if defined(FSMC_Bank2_3)
+/** @defgroup FSMC_LL_NAND_Interrupt FSMC NAND Interrupt
+ * @brief macros to handle NAND interrupts
+ * @{
+ */
+
+/**
+ * @brief Enable the NAND device interrupt.
+ * @param __INSTANCE__ FSMC_NAND instance
+ * @param __BANK__ FSMC_NAND Bank
+ * @param __INTERRUPT__ FSMC_NAND interrupt
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
+ * @arg FSMC_IT_LEVEL: Interrupt level.
+ * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
+ * @retval None
+ */
+#define __FSMC_NAND_ENABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) (((__BANK__) == FSMC_NAND_BANK2) ? \
+ ((__INSTANCE__)->SR2 |= (__INTERRUPT__)) : \
+ ((__INSTANCE__)->SR3 |= (__INTERRUPT__)))
+
+/**
+ * @brief Disable the NAND device interrupt.
+ * @param __INSTANCE__ FSMC_NAND Instance
+ * @param __BANK__ FSMC_NAND Bank
+ * @param __INTERRUPT__ FSMC_NAND interrupt
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
+ * @arg FSMC_IT_LEVEL: Interrupt level.
+ * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
+ * @retval None
+ */
+#define __FSMC_NAND_DISABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) (((__BANK__) == FSMC_NAND_BANK2) ? \
+ ((__INSTANCE__)->SR2 &= ~(__INTERRUPT__)) : \
+ ((__INSTANCE__)->SR3 &= ~(__INTERRUPT__)))
+
+/**
+ * @brief Get flag status of the NAND device.
+ * @param __INSTANCE__ FSMC_NAND Instance
+ * @param __BANK__ FSMC_NAND Bank
+ * @param __FLAG__ FSMC_NAND flag
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
+ * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
+ * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
+ * @arg FSMC_FLAG_FEMPT: FIFO empty flag.
+ * @retval The state of FLAG (SET or RESET).
+ */
+#define __FSMC_NAND_GET_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__BANK__) == FSMC_NAND_BANK2) ? \
+ (((__INSTANCE__)->SR2 &(__FLAG__)) == (__FLAG__)) : \
+ (((__INSTANCE__)->SR3 &(__FLAG__)) == (__FLAG__)))
+
+/**
+ * @brief Clear flag status of the NAND device.
+ * @param __INSTANCE__ FSMC_NAND Instance
+ * @param __BANK__ FSMC_NAND Bank
+ * @param __FLAG__ FSMC_NAND flag
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
+ * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
+ * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
+ * @arg FSMC_FLAG_FEMPT: FIFO empty flag.
+ * @retval None
+ */
+#define __FSMC_NAND_CLEAR_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__BANK__) == FSMC_NAND_BANK2) ? \
+ ((__INSTANCE__)->SR2 &= ~(__FLAG__)) : \
+ ((__INSTANCE__)->SR3 &= ~(__FLAG__)))
+
+/**
+ * @}
+ */
+#endif /* FSMC_Bank2_3 */
+
+#if defined(FSMC_Bank4)
+/** @defgroup FSMC_LL_PCCARD_Interrupt FSMC PCCARD Interrupt
+ * @brief macros to handle PCCARD interrupts
+ * @{
+ */
+
+/**
+ * @brief Enable the PCCARD device interrupt.
+ * @param __INSTANCE__ FSMC_PCCARD instance
+ * @param __INTERRUPT__ FSMC_PCCARD interrupt
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
+ * @arg FSMC_IT_LEVEL: Interrupt level.
+ * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
+ * @retval None
+ */
+#define __FSMC_PCCARD_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SR4 |= (__INTERRUPT__))
+
+/**
+ * @brief Disable the PCCARD device interrupt.
+ * @param __INSTANCE__ FSMC_PCCARD instance
+ * @param __INTERRUPT__ FSMC_PCCARD interrupt
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
+ * @arg FSMC_IT_LEVEL: Interrupt level.
+ * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
+ * @retval None
+ */
+#define __FSMC_PCCARD_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SR4 &= ~(__INTERRUPT__))
+
+/**
+ * @brief Get flag status of the PCCARD device.
+ * @param __INSTANCE__ FSMC_PCCARD instance
+ * @param __FLAG__ FSMC_PCCARD flag
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
+ * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
+ * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
+ * @arg FSMC_FLAG_FEMPT: FIFO empty flag.
+ * @retval The state of FLAG (SET or RESET).
+ */
+#define __FSMC_PCCARD_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->SR4 &(__FLAG__)) == (__FLAG__))
+
+/**
+ * @brief Clear flag status of the PCCARD device.
+ * @param __INSTANCE__ FSMC_PCCARD instance
+ * @param __FLAG__ FSMC_PCCARD flag
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
+ * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
+ * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
+ * @arg FSMC_FLAG_FEMPT: FIFO empty flag.
+ * @retval None
+ */
+#define __FSMC_PCCARD_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->SR4 &= ~(__FLAG__))
+
+/**
+ * @}
+ */
+#endif /* FSMC_Bank4 */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup FSMC_LL_Private_Functions FSMC LL Private Functions
+ * @{
+ */
+
+#if defined(FSMC_Bank1)
+/** @defgroup FSMC_LL_NORSRAM NOR SRAM
+ * @{
+ */
+/** @defgroup FSMC_LL_NORSRAM_Private_Functions_Group1 NOR SRAM Initialization/de-initialization functions
+ * @{
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef *Device,
+ const FSMC_NORSRAM_InitTypeDef *Init);
+HAL_StatusTypeDef FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef *Device,
+ const FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef *Device,
+ const FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank,
+ uint32_t ExtendedMode);
+HAL_StatusTypeDef FSMC_NORSRAM_DeInit(FSMC_NORSRAM_TypeDef *Device,
+ FSMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank);
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_LL_NORSRAM_Private_Functions_Group2 NOR SRAM Control functions
+ * @{
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank);
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+#endif /* FSMC_Bank1 */
+
+#if defined(FSMC_Bank2_3)
+/** @defgroup FSMC_LL_NAND NAND
+ * @{
+ */
+/** @defgroup FSMC_LL_NAND_Private_Functions_Group1 NAND Initialization/de-initialization functions
+ * @{
+ */
+HAL_StatusTypeDef FSMC_NAND_Init(FSMC_NAND_TypeDef *Device, const FSMC_NAND_InitTypeDef *Init);
+HAL_StatusTypeDef FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef *Device,
+ const FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef *Device,
+ const FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NAND_DeInit(FSMC_NAND_TypeDef *Device, uint32_t Bank);
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_LL_NAND_Private_Functions_Group2 NAND Control functions
+ * @{
+ */
+HAL_StatusTypeDef FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef *Device, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef *Device, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NAND_GetECC(const FSMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank,
+ uint32_t Timeout);
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+#endif /* FSMC_Bank2_3 */
+
+#if defined(FSMC_Bank4)
+/** @defgroup FSMC_LL_PCCARD PCCARD
+ * @{
+ */
+/** @defgroup FSMC_LL_PCCARD_Private_Functions_Group1 PCCARD Initialization/de-initialization functions
+ * @{
+ */
+HAL_StatusTypeDef FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef *Device, const FSMC_PCCARD_InitTypeDef *Init);
+HAL_StatusTypeDef FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device,
+ const FSMC_NAND_PCC_TimingTypeDef *Timing);
+HAL_StatusTypeDef FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device,
+ const FSMC_NAND_PCC_TimingTypeDef *Timing);
+HAL_StatusTypeDef FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device,
+ const FSMC_NAND_PCC_TimingTypeDef *Timing);
+HAL_StatusTypeDef FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef *Device);
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+#endif /* FSMC_Bank4 */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32F4xx_LL_FSMC_H */
diff --git a/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usart.h b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usart.h
new file mode 100644
index 0000000..ed83b6c
--- /dev/null
+++ b/cubemx/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usart.h
@@ -0,0 +1,2521 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_ll_usart.h
+ * @author MCD Application Team
+ * @brief Header file of USART LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_LL_USART_H
+#define __STM32F4xx_LL_USART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx.h"
+
+/** @addtogroup STM32F4xx_LL_Driver
+ * @{
+ */
+
+#if defined (USART1) || defined (USART2) || defined (USART3) || defined (USART6) || defined (UART4) || defined (UART5) || defined (UART7) || defined (UART8) || defined (UART9) || defined (UART10)
+
+/** @defgroup USART_LL USART
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup USART_LL_Private_Constants USART Private Constants
+ * @{
+ */
+
+/* Defines used for the bit position in the register and perform offsets*/
+#define USART_POSITION_GTPR_GT USART_GTPR_GT_Pos
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup USART_LL_Private_Macros USART Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/* Exported types ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup USART_LL_ES_INIT USART Exported Init structures
+ * @{
+ */
+
+/**
+ * @brief LL USART Init Structure definition
+ */
+typedef struct
+{
+ uint32_t BaudRate; /*!< This field defines expected Usart communication baud rate.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetBaudRate().*/
+
+ uint32_t DataWidth; /*!< Specifies the number of data bits transmitted or received in a frame.
+ This parameter can be a value of @ref USART_LL_EC_DATAWIDTH.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetDataWidth().*/
+
+ uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
+ This parameter can be a value of @ref USART_LL_EC_STOPBITS.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetStopBitsLength().*/
+
+ uint32_t Parity; /*!< Specifies the parity mode.
+ This parameter can be a value of @ref USART_LL_EC_PARITY.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetParity().*/
+
+ uint32_t TransferDirection; /*!< Specifies whether the Receive and/or Transmit mode is enabled or disabled.
+ This parameter can be a value of @ref USART_LL_EC_DIRECTION.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetTransferDirection().*/
+
+ uint32_t HardwareFlowControl; /*!< Specifies whether the hardware flow control mode is enabled or disabled.
+ This parameter can be a value of @ref USART_LL_EC_HWCONTROL.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetHWFlowCtrl().*/
+
+ uint32_t OverSampling; /*!< Specifies whether USART oversampling mode is 16 or 8.
+ This parameter can be a value of @ref USART_LL_EC_OVERSAMPLING.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetOverSampling().*/
+
+} LL_USART_InitTypeDef;
+
+/**
+ * @brief LL USART Clock Init Structure definition
+ */
+typedef struct
+{
+ uint32_t ClockOutput; /*!< Specifies whether the USART clock is enabled or disabled.
+ This parameter can be a value of @ref USART_LL_EC_CLOCK.
+
+ USART HW configuration can be modified afterwards using unitary functions
+ @ref LL_USART_EnableSCLKOutput() or @ref LL_USART_DisableSCLKOutput().
+ For more details, refer to description of this function. */
+
+ uint32_t ClockPolarity; /*!< Specifies the steady state of the serial clock.
+ This parameter can be a value of @ref USART_LL_EC_POLARITY.
+
+ USART HW configuration can be modified afterwards using unitary functions @ref LL_USART_SetClockPolarity().
+ For more details, refer to description of this function. */
+
+ uint32_t ClockPhase; /*!< Specifies the clock transition on which the bit capture is made.
+ This parameter can be a value of @ref USART_LL_EC_PHASE.
+
+ USART HW configuration can be modified afterwards using unitary functions @ref LL_USART_SetClockPhase().
+ For more details, refer to description of this function. */
+
+ uint32_t LastBitClockPulse; /*!< Specifies whether the clock pulse corresponding to the last transmitted
+ data bit (MSB) has to be output on the SCLK pin in synchronous mode.
+ This parameter can be a value of @ref USART_LL_EC_LASTCLKPULSE.
+
+ USART HW configuration can be modified afterwards using unitary functions @ref LL_USART_SetLastClkPulseOutput().
+ For more details, refer to description of this function. */
+
+} LL_USART_ClockInitTypeDef;
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup USART_LL_Exported_Constants USART Exported Constants
+ * @{
+ */
+
+/** @defgroup USART_LL_EC_GET_FLAG Get Flags Defines
+ * @brief Flags defines which can be used with LL_USART_ReadReg function
+ * @{
+ */
+#define LL_USART_SR_PE USART_SR_PE /*!< Parity error flag */
+#define LL_USART_SR_FE USART_SR_FE /*!< Framing error flag */
+#define LL_USART_SR_NE USART_SR_NE /*!< Noise detected flag */
+#define LL_USART_SR_ORE USART_SR_ORE /*!< Overrun error flag */
+#define LL_USART_SR_IDLE USART_SR_IDLE /*!< Idle line detected flag */
+#define LL_USART_SR_RXNE USART_SR_RXNE /*!< Read data register not empty flag */
+#define LL_USART_SR_TC USART_SR_TC /*!< Transmission complete flag */
+#define LL_USART_SR_TXE USART_SR_TXE /*!< Transmit data register empty flag */
+#define LL_USART_SR_LBD USART_SR_LBD /*!< LIN break detection flag */
+#define LL_USART_SR_CTS USART_SR_CTS /*!< CTS flag */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_IT IT Defines
+ * @brief IT defines which can be used with LL_USART_ReadReg and LL_USART_WriteReg functions
+ * @{
+ */
+#define LL_USART_CR1_IDLEIE USART_CR1_IDLEIE /*!< IDLE interrupt enable */
+#define LL_USART_CR1_RXNEIE USART_CR1_RXNEIE /*!< Read data register not empty interrupt enable */
+#define LL_USART_CR1_TCIE USART_CR1_TCIE /*!< Transmission complete interrupt enable */
+#define LL_USART_CR1_TXEIE USART_CR1_TXEIE /*!< Transmit data register empty interrupt enable */
+#define LL_USART_CR1_PEIE USART_CR1_PEIE /*!< Parity error */
+#define LL_USART_CR2_LBDIE USART_CR2_LBDIE /*!< LIN break detection interrupt enable */
+#define LL_USART_CR3_EIE USART_CR3_EIE /*!< Error interrupt enable */
+#define LL_USART_CR3_CTSIE USART_CR3_CTSIE /*!< CTS interrupt enable */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_DIRECTION Communication Direction
+ * @{
+ */
+#define LL_USART_DIRECTION_NONE 0x00000000U /*!< Transmitter and Receiver are disabled */
+#define LL_USART_DIRECTION_RX USART_CR1_RE /*!< Transmitter is disabled and Receiver is enabled */
+#define LL_USART_DIRECTION_TX USART_CR1_TE /*!< Transmitter is enabled and Receiver is disabled */
+#define LL_USART_DIRECTION_TX_RX (USART_CR1_TE |USART_CR1_RE) /*!< Transmitter and Receiver are enabled */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_PARITY Parity Control
+ * @{
+ */
+#define LL_USART_PARITY_NONE 0x00000000U /*!< Parity control disabled */
+#define LL_USART_PARITY_EVEN USART_CR1_PCE /*!< Parity control enabled and Even Parity is selected */
+#define LL_USART_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) /*!< Parity control enabled and Odd Parity is selected */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_WAKEUP Wakeup
+ * @{
+ */
+#define LL_USART_WAKEUP_IDLELINE 0x00000000U /*!< USART wake up from Mute mode on Idle Line */
+#define LL_USART_WAKEUP_ADDRESSMARK USART_CR1_WAKE /*!< USART wake up from Mute mode on Address Mark */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_DATAWIDTH Datawidth
+ * @{
+ */
+#define LL_USART_DATAWIDTH_8B 0x00000000U /*!< 8 bits word length : Start bit, 8 data bits, n stop bits */
+#define LL_USART_DATAWIDTH_9B USART_CR1_M /*!< 9 bits word length : Start bit, 9 data bits, n stop bits */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_OVERSAMPLING Oversampling
+ * @{
+ */
+#define LL_USART_OVERSAMPLING_16 0x00000000U /*!< Oversampling by 16 */
+#define LL_USART_OVERSAMPLING_8 USART_CR1_OVER8 /*!< Oversampling by 8 */
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup USART_LL_EC_CLOCK Clock Signal
+ * @{
+ */
+
+#define LL_USART_CLOCK_DISABLE 0x00000000U /*!< Clock signal not provided */
+#define LL_USART_CLOCK_ENABLE USART_CR2_CLKEN /*!< Clock signal provided */
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/** @defgroup USART_LL_EC_LASTCLKPULSE Last Clock Pulse
+ * @{
+ */
+#define LL_USART_LASTCLKPULSE_NO_OUTPUT 0x00000000U /*!< The clock pulse of the last data bit is not output to the SCLK pin */
+#define LL_USART_LASTCLKPULSE_OUTPUT USART_CR2_LBCL /*!< The clock pulse of the last data bit is output to the SCLK pin */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_PHASE Clock Phase
+ * @{
+ */
+#define LL_USART_PHASE_1EDGE 0x00000000U /*!< The first clock transition is the first data capture edge */
+#define LL_USART_PHASE_2EDGE USART_CR2_CPHA /*!< The second clock transition is the first data capture edge */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_POLARITY Clock Polarity
+ * @{
+ */
+#define LL_USART_POLARITY_LOW 0x00000000U /*!< Steady low value on SCLK pin outside transmission window*/
+#define LL_USART_POLARITY_HIGH USART_CR2_CPOL /*!< Steady high value on SCLK pin outside transmission window */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_STOPBITS Stop Bits
+ * @{
+ */
+#define LL_USART_STOPBITS_0_5 USART_CR2_STOP_0 /*!< 0.5 stop bit */
+#define LL_USART_STOPBITS_1 0x00000000U /*!< 1 stop bit */
+#define LL_USART_STOPBITS_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< 1.5 stop bits */
+#define LL_USART_STOPBITS_2 USART_CR2_STOP_1 /*!< 2 stop bits */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_HWCONTROL Hardware Control
+ * @{
+ */
+#define LL_USART_HWCONTROL_NONE 0x00000000U /*!< CTS and RTS hardware flow control disabled */
+#define LL_USART_HWCONTROL_RTS USART_CR3_RTSE /*!< RTS output enabled, data is only requested when there is space in the receive buffer */
+#define LL_USART_HWCONTROL_CTS USART_CR3_CTSE /*!< CTS mode enabled, data is only transmitted when the nCTS input is asserted (tied to 0) */
+#define LL_USART_HWCONTROL_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE) /*!< CTS and RTS hardware flow control enabled */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_IRDA_POWER IrDA Power
+ * @{
+ */
+#define LL_USART_IRDA_POWER_NORMAL 0x00000000U /*!< IrDA normal power mode */
+#define LL_USART_IRDA_POWER_LOW USART_CR3_IRLP /*!< IrDA low power mode */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_LINBREAK_DETECT LIN Break Detection Length
+ * @{
+ */
+#define LL_USART_LINBREAK_DETECT_10B 0x00000000U /*!< 10-bit break detection method selected */
+#define LL_USART_LINBREAK_DETECT_11B USART_CR2_LBDL /*!< 11-bit break detection method selected */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup USART_LL_Exported_Macros USART Exported Macros
+ * @{
+ */
+
+/** @defgroup USART_LL_EM_WRITE_READ Common Write and read registers Macros
+ * @{
+ */
+
+/**
+ * @brief Write a value in USART register
+ * @param __INSTANCE__ USART Instance
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_USART_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in USART register
+ * @param __INSTANCE__ USART Instance
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_USART_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EM_Exported_Macros_Helper Exported Macros Helper
+ * @{
+ */
+
+/**
+ * @brief Compute USARTDIV value according to Peripheral Clock and
+ * expected Baud Rate in 8 bits sampling mode (32 bits value of USARTDIV is returned)
+ * @param __PERIPHCLK__ Peripheral Clock frequency used for USART instance
+ * @param __BAUDRATE__ Baud rate value to achieve
+ * @retval USARTDIV value to be used for BRR register filling in OverSampling_8 case
+ */
+#define __LL_USART_DIV_SAMPLING8_100(__PERIPHCLK__, __BAUDRATE__) ((uint32_t)((((uint64_t)(__PERIPHCLK__))*25)/(2*((uint64_t)(__BAUDRATE__)))))
+#define __LL_USART_DIVMANT_SAMPLING8(__PERIPHCLK__, __BAUDRATE__) (__LL_USART_DIV_SAMPLING8_100((__PERIPHCLK__), (__BAUDRATE__))/100)
+#define __LL_USART_DIVFRAQ_SAMPLING8(__PERIPHCLK__, __BAUDRATE__) ((((__LL_USART_DIV_SAMPLING8_100((__PERIPHCLK__), (__BAUDRATE__)) - (__LL_USART_DIVMANT_SAMPLING8((__PERIPHCLK__), (__BAUDRATE__)) * 100)) * 8)\
+ + 50) / 100)
+/* UART BRR = mantissa + overflow + fraction
+ = (UART DIVMANT << 4) + ((UART DIVFRAQ & 0xF8) << 1) + (UART DIVFRAQ & 0x07) */
+#define __LL_USART_DIV_SAMPLING8(__PERIPHCLK__, __BAUDRATE__) (((__LL_USART_DIVMANT_SAMPLING8((__PERIPHCLK__), (__BAUDRATE__)) << 4) + \
+ ((__LL_USART_DIVFRAQ_SAMPLING8((__PERIPHCLK__), (__BAUDRATE__)) & 0xF8) << 1)) + \
+ (__LL_USART_DIVFRAQ_SAMPLING8((__PERIPHCLK__), (__BAUDRATE__)) & 0x07))
+
+/**
+ * @brief Compute USARTDIV value according to Peripheral Clock and
+ * expected Baud Rate in 16 bits sampling mode (32 bits value of USARTDIV is returned)
+ * @param __PERIPHCLK__ Peripheral Clock frequency used for USART instance
+ * @param __BAUDRATE__ Baud rate value to achieve
+ * @retval USARTDIV value to be used for BRR register filling in OverSampling_16 case
+ */
+#define __LL_USART_DIV_SAMPLING16_100(__PERIPHCLK__, __BAUDRATE__) ((uint32_t)((((uint64_t)(__PERIPHCLK__))*25)/(4*((uint64_t)(__BAUDRATE__)))))
+#define __LL_USART_DIVMANT_SAMPLING16(__PERIPHCLK__, __BAUDRATE__) (__LL_USART_DIV_SAMPLING16_100((__PERIPHCLK__), (__BAUDRATE__))/100)
+#define __LL_USART_DIVFRAQ_SAMPLING16(__PERIPHCLK__, __BAUDRATE__) ((((__LL_USART_DIV_SAMPLING16_100((__PERIPHCLK__), (__BAUDRATE__)) - (__LL_USART_DIVMANT_SAMPLING16((__PERIPHCLK__), (__BAUDRATE__)) * 100)) * 16)\
+ + 50) / 100)
+/* USART BRR = mantissa + overflow + fraction
+ = (USART DIVMANT << 4) + (USART DIVFRAQ & 0xF0) + (USART DIVFRAQ & 0x0F) */
+#define __LL_USART_DIV_SAMPLING16(__PERIPHCLK__, __BAUDRATE__) (((__LL_USART_DIVMANT_SAMPLING16((__PERIPHCLK__), (__BAUDRATE__)) << 4) + \
+ (__LL_USART_DIVFRAQ_SAMPLING16((__PERIPHCLK__), (__BAUDRATE__)) & 0xF0)) + \
+ (__LL_USART_DIVFRAQ_SAMPLING16((__PERIPHCLK__), (__BAUDRATE__)) & 0x0F))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup USART_LL_Exported_Functions USART Exported Functions
+ * @{
+ */
+
+/** @defgroup USART_LL_EF_Configuration Configuration functions
+ * @{
+ */
+
+/**
+ * @brief USART Enable
+ * @rmtoll CR1 UE LL_USART_Enable
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_Enable(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR1, USART_CR1_UE);
+}
+
+/**
+ * @brief USART Disable (all USART prescalers and outputs are disabled)
+ * @note When USART is disabled, USART prescalers and outputs are stopped immediately,
+ * and current operations are discarded. The configuration of the USART is kept, but all the status
+ * flags, in the USARTx_SR are set to their default values.
+ * @rmtoll CR1 UE LL_USART_Disable
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_Disable(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR1, USART_CR1_UE);
+}
+
+/**
+ * @brief Indicate if USART is enabled
+ * @rmtoll CR1 UE LL_USART_IsEnabled
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabled(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_UE) == (USART_CR1_UE));
+}
+
+/**
+ * @brief Receiver Enable (Receiver is enabled and begins searching for a start bit)
+ * @rmtoll CR1 RE LL_USART_EnableDirectionRx
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableDirectionRx(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RE);
+}
+
+/**
+ * @brief Receiver Disable
+ * @rmtoll CR1 RE LL_USART_DisableDirectionRx
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableDirectionRx(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RE);
+}
+
+/**
+ * @brief Transmitter Enable
+ * @rmtoll CR1 TE LL_USART_EnableDirectionTx
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableDirectionTx(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TE);
+}
+
+/**
+ * @brief Transmitter Disable
+ * @rmtoll CR1 TE LL_USART_DisableDirectionTx
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableDirectionTx(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TE);
+}
+
+/**
+ * @brief Configure simultaneously enabled/disabled states
+ * of Transmitter and Receiver
+ * @rmtoll CR1 RE LL_USART_SetTransferDirection\n
+ * CR1 TE LL_USART_SetTransferDirection
+ * @param USARTx USART Instance
+ * @param TransferDirection This parameter can be one of the following values:
+ * @arg @ref LL_USART_DIRECTION_NONE
+ * @arg @ref LL_USART_DIRECTION_RX
+ * @arg @ref LL_USART_DIRECTION_TX
+ * @arg @ref LL_USART_DIRECTION_TX_RX
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetTransferDirection(USART_TypeDef *USARTx, uint32_t TransferDirection)
+{
+ ATOMIC_MODIFY_REG(USARTx->CR1, USART_CR1_RE | USART_CR1_TE, TransferDirection);
+}
+
+/**
+ * @brief Return enabled/disabled states of Transmitter and Receiver
+ * @rmtoll CR1 RE LL_USART_GetTransferDirection\n
+ * CR1 TE LL_USART_GetTransferDirection
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_DIRECTION_NONE
+ * @arg @ref LL_USART_DIRECTION_RX
+ * @arg @ref LL_USART_DIRECTION_TX
+ * @arg @ref LL_USART_DIRECTION_TX_RX
+ */
+__STATIC_INLINE uint32_t LL_USART_GetTransferDirection(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_RE | USART_CR1_TE));
+}
+
+/**
+ * @brief Configure Parity (enabled/disabled and parity mode if enabled).
+ * @note This function selects if hardware parity control (generation and detection) is enabled or disabled.
+ * When the parity control is enabled (Odd or Even), computed parity bit is inserted at the MSB position
+ * (9th or 8th bit depending on data width) and parity is checked on the received data.
+ * @rmtoll CR1 PS LL_USART_SetParity\n
+ * CR1 PCE LL_USART_SetParity
+ * @param USARTx USART Instance
+ * @param Parity This parameter can be one of the following values:
+ * @arg @ref LL_USART_PARITY_NONE
+ * @arg @ref LL_USART_PARITY_EVEN
+ * @arg @ref LL_USART_PARITY_ODD
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetParity(USART_TypeDef *USARTx, uint32_t Parity)
+{
+ MODIFY_REG(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE, Parity);
+}
+
+/**
+ * @brief Return Parity configuration (enabled/disabled and parity mode if enabled)
+ * @rmtoll CR1 PS LL_USART_GetParity\n
+ * CR1 PCE LL_USART_GetParity
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_PARITY_NONE
+ * @arg @ref LL_USART_PARITY_EVEN
+ * @arg @ref LL_USART_PARITY_ODD
+ */
+__STATIC_INLINE uint32_t LL_USART_GetParity(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE));
+}
+
+/**
+ * @brief Set Receiver Wake Up method from Mute mode.
+ * @rmtoll CR1 WAKE LL_USART_SetWakeUpMethod
+ * @param USARTx USART Instance
+ * @param Method This parameter can be one of the following values:
+ * @arg @ref LL_USART_WAKEUP_IDLELINE
+ * @arg @ref LL_USART_WAKEUP_ADDRESSMARK
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetWakeUpMethod(USART_TypeDef *USARTx, uint32_t Method)
+{
+ MODIFY_REG(USARTx->CR1, USART_CR1_WAKE, Method);
+}
+
+/**
+ * @brief Return Receiver Wake Up method from Mute mode
+ * @rmtoll CR1 WAKE LL_USART_GetWakeUpMethod
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_WAKEUP_IDLELINE
+ * @arg @ref LL_USART_WAKEUP_ADDRESSMARK
+ */
+__STATIC_INLINE uint32_t LL_USART_GetWakeUpMethod(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_WAKE));
+}
+
+/**
+ * @brief Set Word length (i.e. nb of data bits, excluding start and stop bits)
+ * @rmtoll CR1 M LL_USART_SetDataWidth
+ * @param USARTx USART Instance
+ * @param DataWidth This parameter can be one of the following values:
+ * @arg @ref LL_USART_DATAWIDTH_8B
+ * @arg @ref LL_USART_DATAWIDTH_9B
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetDataWidth(USART_TypeDef *USARTx, uint32_t DataWidth)
+{
+ MODIFY_REG(USARTx->CR1, USART_CR1_M, DataWidth);
+}
+
+/**
+ * @brief Return Word length (i.e. nb of data bits, excluding start and stop bits)
+ * @rmtoll CR1 M LL_USART_GetDataWidth
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_DATAWIDTH_8B
+ * @arg @ref LL_USART_DATAWIDTH_9B
+ */
+__STATIC_INLINE uint32_t LL_USART_GetDataWidth(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_M));
+}
+
+/**
+ * @brief Set Oversampling to 8-bit or 16-bit mode
+ * @rmtoll CR1 OVER8 LL_USART_SetOverSampling
+ * @param USARTx USART Instance
+ * @param OverSampling This parameter can be one of the following values:
+ * @arg @ref LL_USART_OVERSAMPLING_16
+ * @arg @ref LL_USART_OVERSAMPLING_8
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetOverSampling(USART_TypeDef *USARTx, uint32_t OverSampling)
+{
+ MODIFY_REG(USARTx->CR1, USART_CR1_OVER8, OverSampling);
+}
+
+/**
+ * @brief Return Oversampling mode
+ * @rmtoll CR1 OVER8 LL_USART_GetOverSampling
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_OVERSAMPLING_16
+ * @arg @ref LL_USART_OVERSAMPLING_8
+ */
+__STATIC_INLINE uint32_t LL_USART_GetOverSampling(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_OVER8));
+}
+
+/**
+ * @brief Configure if Clock pulse of the last data bit is output to the SCLK pin or not
+ * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 LBCL LL_USART_SetLastClkPulseOutput
+ * @param USARTx USART Instance
+ * @param LastBitClockPulse This parameter can be one of the following values:
+ * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT
+ * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetLastClkPulseOutput(USART_TypeDef *USARTx, uint32_t LastBitClockPulse)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_LBCL, LastBitClockPulse);
+}
+
+/**
+ * @brief Retrieve Clock pulse of the last data bit output configuration
+ * (Last bit Clock pulse output to the SCLK pin or not)
+ * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 LBCL LL_USART_GetLastClkPulseOutput
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT
+ * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT
+ */
+__STATIC_INLINE uint32_t LL_USART_GetLastClkPulseOutput(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_LBCL));
+}
+
+/**
+ * @brief Select the phase of the clock output on the SCLK pin in synchronous mode
+ * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CPHA LL_USART_SetClockPhase
+ * @param USARTx USART Instance
+ * @param ClockPhase This parameter can be one of the following values:
+ * @arg @ref LL_USART_PHASE_1EDGE
+ * @arg @ref LL_USART_PHASE_2EDGE
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetClockPhase(USART_TypeDef *USARTx, uint32_t ClockPhase)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_CPHA, ClockPhase);
+}
+
+/**
+ * @brief Return phase of the clock output on the SCLK pin in synchronous mode
+ * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CPHA LL_USART_GetClockPhase
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_PHASE_1EDGE
+ * @arg @ref LL_USART_PHASE_2EDGE
+ */
+__STATIC_INLINE uint32_t LL_USART_GetClockPhase(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_CPHA));
+}
+
+/**
+ * @brief Select the polarity of the clock output on the SCLK pin in synchronous mode
+ * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CPOL LL_USART_SetClockPolarity
+ * @param USARTx USART Instance
+ * @param ClockPolarity This parameter can be one of the following values:
+ * @arg @ref LL_USART_POLARITY_LOW
+ * @arg @ref LL_USART_POLARITY_HIGH
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetClockPolarity(USART_TypeDef *USARTx, uint32_t ClockPolarity)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_CPOL, ClockPolarity);
+}
+
+/**
+ * @brief Return polarity of the clock output on the SCLK pin in synchronous mode
+ * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CPOL LL_USART_GetClockPolarity
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_POLARITY_LOW
+ * @arg @ref LL_USART_POLARITY_HIGH
+ */
+__STATIC_INLINE uint32_t LL_USART_GetClockPolarity(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_CPOL));
+}
+
+/**
+ * @brief Configure Clock signal format (Phase Polarity and choice about output of last bit clock pulse)
+ * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clock Phase configuration using @ref LL_USART_SetClockPhase() function
+ * - Clock Polarity configuration using @ref LL_USART_SetClockPolarity() function
+ * - Output of Last bit Clock pulse configuration using @ref LL_USART_SetLastClkPulseOutput() function
+ * @rmtoll CR2 CPHA LL_USART_ConfigClock\n
+ * CR2 CPOL LL_USART_ConfigClock\n
+ * CR2 LBCL LL_USART_ConfigClock
+ * @param USARTx USART Instance
+ * @param Phase This parameter can be one of the following values:
+ * @arg @ref LL_USART_PHASE_1EDGE
+ * @arg @ref LL_USART_PHASE_2EDGE
+ * @param Polarity This parameter can be one of the following values:
+ * @arg @ref LL_USART_POLARITY_LOW
+ * @arg @ref LL_USART_POLARITY_HIGH
+ * @param LBCPOutput This parameter can be one of the following values:
+ * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT
+ * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigClock(USART_TypeDef *USARTx, uint32_t Phase, uint32_t Polarity, uint32_t LBCPOutput)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_LBCL, Phase | Polarity | LBCPOutput);
+}
+
+/**
+ * @brief Enable Clock output on SCLK pin
+ * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CLKEN LL_USART_EnableSCLKOutput
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableSCLKOutput(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR2, USART_CR2_CLKEN);
+}
+
+/**
+ * @brief Disable Clock output on SCLK pin
+ * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CLKEN LL_USART_DisableSCLKOutput
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableSCLKOutput(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR2, USART_CR2_CLKEN);
+}
+
+/**
+ * @brief Indicate if Clock output on SCLK pin is enabled
+ * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CLKEN LL_USART_IsEnabledSCLKOutput
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledSCLKOutput(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR2, USART_CR2_CLKEN) == (USART_CR2_CLKEN));
+}
+
+/**
+ * @brief Set the length of the stop bits
+ * @rmtoll CR2 STOP LL_USART_SetStopBitsLength
+ * @param USARTx USART Instance
+ * @param StopBits This parameter can be one of the following values:
+ * @arg @ref LL_USART_STOPBITS_0_5
+ * @arg @ref LL_USART_STOPBITS_1
+ * @arg @ref LL_USART_STOPBITS_1_5
+ * @arg @ref LL_USART_STOPBITS_2
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetStopBitsLength(USART_TypeDef *USARTx, uint32_t StopBits)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_STOP, StopBits);
+}
+
+/**
+ * @brief Retrieve the length of the stop bits
+ * @rmtoll CR2 STOP LL_USART_GetStopBitsLength
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_STOPBITS_0_5
+ * @arg @ref LL_USART_STOPBITS_1
+ * @arg @ref LL_USART_STOPBITS_1_5
+ * @arg @ref LL_USART_STOPBITS_2
+ */
+__STATIC_INLINE uint32_t LL_USART_GetStopBitsLength(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_STOP));
+}
+
+/**
+ * @brief Configure Character frame format (Datawidth, Parity control, Stop Bits)
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Data Width configuration using @ref LL_USART_SetDataWidth() function
+ * - Parity Control and mode configuration using @ref LL_USART_SetParity() function
+ * - Stop bits configuration using @ref LL_USART_SetStopBitsLength() function
+ * @rmtoll CR1 PS LL_USART_ConfigCharacter\n
+ * CR1 PCE LL_USART_ConfigCharacter\n
+ * CR1 M LL_USART_ConfigCharacter\n
+ * CR2 STOP LL_USART_ConfigCharacter
+ * @param USARTx USART Instance
+ * @param DataWidth This parameter can be one of the following values:
+ * @arg @ref LL_USART_DATAWIDTH_8B
+ * @arg @ref LL_USART_DATAWIDTH_9B
+ * @param Parity This parameter can be one of the following values:
+ * @arg @ref LL_USART_PARITY_NONE
+ * @arg @ref LL_USART_PARITY_EVEN
+ * @arg @ref LL_USART_PARITY_ODD
+ * @param StopBits This parameter can be one of the following values:
+ * @arg @ref LL_USART_STOPBITS_0_5
+ * @arg @ref LL_USART_STOPBITS_1
+ * @arg @ref LL_USART_STOPBITS_1_5
+ * @arg @ref LL_USART_STOPBITS_2
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigCharacter(USART_TypeDef *USARTx, uint32_t DataWidth, uint32_t Parity,
+ uint32_t StopBits)
+{
+ MODIFY_REG(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE | USART_CR1_M, Parity | DataWidth);
+ MODIFY_REG(USARTx->CR2, USART_CR2_STOP, StopBits);
+}
+
+/**
+ * @brief Set Address of the USART node.
+ * @note This is used in multiprocessor communication during Mute mode or Stop mode,
+ * for wake up with address mark detection.
+ * @rmtoll CR2 ADD LL_USART_SetNodeAddress
+ * @param USARTx USART Instance
+ * @param NodeAddress 4 bit Address of the USART node.
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetNodeAddress(USART_TypeDef *USARTx, uint32_t NodeAddress)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_ADD, (NodeAddress & USART_CR2_ADD));
+}
+
+/**
+ * @brief Return 4 bit Address of the USART node as set in ADD field of CR2.
+ * @note only 4bits (b3-b0) of returned value are relevant (b31-b4 are not relevant)
+ * @rmtoll CR2 ADD LL_USART_GetNodeAddress
+ * @param USARTx USART Instance
+ * @retval Address of the USART node (Value between Min_Data=0 and Max_Data=255)
+ */
+__STATIC_INLINE uint32_t LL_USART_GetNodeAddress(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_ADD));
+}
+
+/**
+ * @brief Enable RTS HW Flow Control
+ * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 RTSE LL_USART_EnableRTSHWFlowCtrl
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableRTSHWFlowCtrl(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_RTSE);
+}
+
+/**
+ * @brief Disable RTS HW Flow Control
+ * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 RTSE LL_USART_DisableRTSHWFlowCtrl
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableRTSHWFlowCtrl(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_RTSE);
+}
+
+/**
+ * @brief Enable CTS HW Flow Control
+ * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 CTSE LL_USART_EnableCTSHWFlowCtrl
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableCTSHWFlowCtrl(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_CTSE);
+}
+
+/**
+ * @brief Disable CTS HW Flow Control
+ * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 CTSE LL_USART_DisableCTSHWFlowCtrl
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableCTSHWFlowCtrl(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_CTSE);
+}
+
+/**
+ * @brief Configure HW Flow Control mode (both CTS and RTS)
+ * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 RTSE LL_USART_SetHWFlowCtrl\n
+ * CR3 CTSE LL_USART_SetHWFlowCtrl
+ * @param USARTx USART Instance
+ * @param HardwareFlowControl This parameter can be one of the following values:
+ * @arg @ref LL_USART_HWCONTROL_NONE
+ * @arg @ref LL_USART_HWCONTROL_RTS
+ * @arg @ref LL_USART_HWCONTROL_CTS
+ * @arg @ref LL_USART_HWCONTROL_RTS_CTS
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetHWFlowCtrl(USART_TypeDef *USARTx, uint32_t HardwareFlowControl)
+{
+ MODIFY_REG(USARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE, HardwareFlowControl);
+}
+
+/**
+ * @brief Return HW Flow Control configuration (both CTS and RTS)
+ * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 RTSE LL_USART_GetHWFlowCtrl\n
+ * CR3 CTSE LL_USART_GetHWFlowCtrl
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_HWCONTROL_NONE
+ * @arg @ref LL_USART_HWCONTROL_RTS
+ * @arg @ref LL_USART_HWCONTROL_CTS
+ * @arg @ref LL_USART_HWCONTROL_RTS_CTS
+ */
+__STATIC_INLINE uint32_t LL_USART_GetHWFlowCtrl(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE));
+}
+
+/**
+ * @brief Enable One bit sampling method
+ * @rmtoll CR3 ONEBIT LL_USART_EnableOneBitSamp
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableOneBitSamp(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_ONEBIT);
+}
+
+/**
+ * @brief Disable One bit sampling method
+ * @rmtoll CR3 ONEBIT LL_USART_DisableOneBitSamp
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableOneBitSamp(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_ONEBIT);
+}
+
+/**
+ * @brief Indicate if One bit sampling method is enabled
+ * @rmtoll CR3 ONEBIT LL_USART_IsEnabledOneBitSamp
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledOneBitSamp(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_ONEBIT) == (USART_CR3_ONEBIT));
+}
+
+/**
+ * @brief Configure USART BRR register for achieving expected Baud Rate value.
+ * @note Compute and set USARTDIV value in BRR Register (full BRR content)
+ * according to used Peripheral Clock, Oversampling mode, and expected Baud Rate values
+ * @note Peripheral clock and Baud rate values provided as function parameters should be valid
+ * (Baud rate value != 0)
+ * @rmtoll BRR BRR LL_USART_SetBaudRate
+ * @param USARTx USART Instance
+ * @param PeriphClk Peripheral Clock
+ * @param OverSampling This parameter can be one of the following values:
+ * @arg @ref LL_USART_OVERSAMPLING_16
+ * @arg @ref LL_USART_OVERSAMPLING_8
+ * @param BaudRate Baud Rate
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetBaudRate(USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t OverSampling,
+ uint32_t BaudRate)
+{
+ if (OverSampling == LL_USART_OVERSAMPLING_8)
+ {
+ USARTx->BRR = (uint16_t)(__LL_USART_DIV_SAMPLING8(PeriphClk, BaudRate));
+ }
+ else
+ {
+ USARTx->BRR = (uint16_t)(__LL_USART_DIV_SAMPLING16(PeriphClk, BaudRate));
+ }
+}
+
+/**
+ * @brief Return current Baud Rate value, according to USARTDIV present in BRR register
+ * (full BRR content), and to used Peripheral Clock and Oversampling mode values
+ * @note In case of non-initialized or invalid value stored in BRR register, value 0 will be returned.
+ * @rmtoll BRR BRR LL_USART_GetBaudRate
+ * @param USARTx USART Instance
+ * @param PeriphClk Peripheral Clock
+ * @param OverSampling This parameter can be one of the following values:
+ * @arg @ref LL_USART_OVERSAMPLING_16
+ * @arg @ref LL_USART_OVERSAMPLING_8
+ * @retval Baud Rate
+ */
+__STATIC_INLINE uint32_t LL_USART_GetBaudRate(const USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t OverSampling)
+{
+ uint32_t usartdiv = 0x0U;
+ uint32_t brrresult = 0x0U;
+
+ usartdiv = USARTx->BRR;
+
+ if (OverSampling == LL_USART_OVERSAMPLING_8)
+ {
+ if ((usartdiv & 0xFFF7U) != 0U)
+ {
+ usartdiv = (uint16_t)((usartdiv & 0xFFF0U) | ((usartdiv & 0x0007U) << 1U)) ;
+ brrresult = (PeriphClk * 2U) / usartdiv;
+ }
+ }
+ else
+ {
+ if ((usartdiv & 0xFFFFU) != 0U)
+ {
+ brrresult = PeriphClk / usartdiv;
+ }
+ }
+ return (brrresult);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_Configuration_IRDA Configuration functions related to Irda feature
+ * @{
+ */
+
+/**
+ * @brief Enable IrDA mode
+ * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll CR3 IREN LL_USART_EnableIrda
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIrda(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_IREN);
+}
+
+/**
+ * @brief Disable IrDA mode
+ * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll CR3 IREN LL_USART_DisableIrda
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIrda(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_IREN);
+}
+
+/**
+ * @brief Indicate if IrDA mode is enabled
+ * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll CR3 IREN LL_USART_IsEnabledIrda
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIrda(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_IREN) == (USART_CR3_IREN));
+}
+
+/**
+ * @brief Configure IrDA Power Mode (Normal or Low Power)
+ * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll CR3 IRLP LL_USART_SetIrdaPowerMode
+ * @param USARTx USART Instance
+ * @param PowerMode This parameter can be one of the following values:
+ * @arg @ref LL_USART_IRDA_POWER_NORMAL
+ * @arg @ref LL_USART_IRDA_POWER_LOW
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetIrdaPowerMode(USART_TypeDef *USARTx, uint32_t PowerMode)
+{
+ MODIFY_REG(USARTx->CR3, USART_CR3_IRLP, PowerMode);
+}
+
+/**
+ * @brief Retrieve IrDA Power Mode configuration (Normal or Low Power)
+ * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll CR3 IRLP LL_USART_GetIrdaPowerMode
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_IRDA_POWER_NORMAL
+ * @arg @ref LL_USART_PHASE_2EDGE
+ */
+__STATIC_INLINE uint32_t LL_USART_GetIrdaPowerMode(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_IRLP));
+}
+
+/**
+ * @brief Set Irda prescaler value, used for dividing the USART clock source
+ * to achieve the Irda Low Power frequency (8 bits value)
+ * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll GTPR PSC LL_USART_SetIrdaPrescaler
+ * @param USARTx USART Instance
+ * @param PrescalerValue Value between Min_Data=0x00 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetIrdaPrescaler(USART_TypeDef *USARTx, uint32_t PrescalerValue)
+{
+ MODIFY_REG(USARTx->GTPR, USART_GTPR_PSC, PrescalerValue);
+}
+
+/**
+ * @brief Return Irda prescaler value, used for dividing the USART clock source
+ * to achieve the Irda Low Power frequency (8 bits value)
+ * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll GTPR PSC LL_USART_GetIrdaPrescaler
+ * @param USARTx USART Instance
+ * @retval Irda prescaler value (Value between Min_Data=0x00 and Max_Data=0xFF)
+ */
+__STATIC_INLINE uint32_t LL_USART_GetIrdaPrescaler(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_PSC));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_Configuration_Smartcard Configuration functions related to Smartcard feature
+ * @{
+ */
+
+/**
+ * @brief Enable Smartcard NACK transmission
+ * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll CR3 NACK LL_USART_EnableSmartcardNACK
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableSmartcardNACK(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_NACK);
+}
+
+/**
+ * @brief Disable Smartcard NACK transmission
+ * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll CR3 NACK LL_USART_DisableSmartcardNACK
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableSmartcardNACK(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_NACK);
+}
+
+/**
+ * @brief Indicate if Smartcard NACK transmission is enabled
+ * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll CR3 NACK LL_USART_IsEnabledSmartcardNACK
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledSmartcardNACK(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_NACK) == (USART_CR3_NACK));
+}
+
+/**
+ * @brief Enable Smartcard mode
+ * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll CR3 SCEN LL_USART_EnableSmartcard
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableSmartcard(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_SCEN);
+}
+
+/**
+ * @brief Disable Smartcard mode
+ * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll CR3 SCEN LL_USART_DisableSmartcard
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableSmartcard(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_SCEN);
+}
+
+/**
+ * @brief Indicate if Smartcard mode is enabled
+ * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll CR3 SCEN LL_USART_IsEnabledSmartcard
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledSmartcard(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_SCEN) == (USART_CR3_SCEN));
+}
+
+/**
+ * @brief Set Smartcard prescaler value, used for dividing the USART clock
+ * source to provide the SMARTCARD Clock (5 bits value)
+ * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll GTPR PSC LL_USART_SetSmartcardPrescaler
+ * @param USARTx USART Instance
+ * @param PrescalerValue Value between Min_Data=0 and Max_Data=31
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetSmartcardPrescaler(USART_TypeDef *USARTx, uint32_t PrescalerValue)
+{
+ MODIFY_REG(USARTx->GTPR, USART_GTPR_PSC, PrescalerValue);
+}
+
+/**
+ * @brief Return Smartcard prescaler value, used for dividing the USART clock
+ * source to provide the SMARTCARD Clock (5 bits value)
+ * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll GTPR PSC LL_USART_GetSmartcardPrescaler
+ * @param USARTx USART Instance
+ * @retval Smartcard prescaler value (Value between Min_Data=0 and Max_Data=31)
+ */
+__STATIC_INLINE uint32_t LL_USART_GetSmartcardPrescaler(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_PSC));
+}
+
+/**
+ * @brief Set Smartcard Guard time value, expressed in nb of baud clocks periods
+ * (GT[7:0] bits : Guard time value)
+ * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll GTPR GT LL_USART_SetSmartcardGuardTime
+ * @param USARTx USART Instance
+ * @param GuardTime Value between Min_Data=0x00 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetSmartcardGuardTime(USART_TypeDef *USARTx, uint32_t GuardTime)
+{
+ MODIFY_REG(USARTx->GTPR, USART_GTPR_GT, GuardTime << USART_POSITION_GTPR_GT);
+}
+
+/**
+ * @brief Return Smartcard Guard time value, expressed in nb of baud clocks periods
+ * (GT[7:0] bits : Guard time value)
+ * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll GTPR GT LL_USART_GetSmartcardGuardTime
+ * @param USARTx USART Instance
+ * @retval Smartcard Guard time value (Value between Min_Data=0x00 and Max_Data=0xFF)
+ */
+__STATIC_INLINE uint32_t LL_USART_GetSmartcardGuardTime(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_GT) >> USART_POSITION_GTPR_GT);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_Configuration_HalfDuplex Configuration functions related to Half Duplex feature
+ * @{
+ */
+
+/**
+ * @brief Enable Single Wire Half-Duplex mode
+ * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not
+ * Half-Duplex mode is supported by the USARTx instance.
+ * @rmtoll CR3 HDSEL LL_USART_EnableHalfDuplex
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableHalfDuplex(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_HDSEL);
+}
+
+/**
+ * @brief Disable Single Wire Half-Duplex mode
+ * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not
+ * Half-Duplex mode is supported by the USARTx instance.
+ * @rmtoll CR3 HDSEL LL_USART_DisableHalfDuplex
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableHalfDuplex(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_HDSEL);
+}
+
+/**
+ * @brief Indicate if Single Wire Half-Duplex mode is enabled
+ * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not
+ * Half-Duplex mode is supported by the USARTx instance.
+ * @rmtoll CR3 HDSEL LL_USART_IsEnabledHalfDuplex
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledHalfDuplex(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_HDSEL) == (USART_CR3_HDSEL));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_Configuration_LIN Configuration functions related to LIN feature
+ * @{
+ */
+
+/**
+ * @brief Set LIN Break Detection Length
+ * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LBDL LL_USART_SetLINBrkDetectionLen
+ * @param USARTx USART Instance
+ * @param LINBDLength This parameter can be one of the following values:
+ * @arg @ref LL_USART_LINBREAK_DETECT_10B
+ * @arg @ref LL_USART_LINBREAK_DETECT_11B
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetLINBrkDetectionLen(USART_TypeDef *USARTx, uint32_t LINBDLength)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_LBDL, LINBDLength);
+}
+
+/**
+ * @brief Return LIN Break Detection Length
+ * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LBDL LL_USART_GetLINBrkDetectionLen
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_LINBREAK_DETECT_10B
+ * @arg @ref LL_USART_LINBREAK_DETECT_11B
+ */
+__STATIC_INLINE uint32_t LL_USART_GetLINBrkDetectionLen(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_LBDL));
+}
+
+/**
+ * @brief Enable LIN mode
+ * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LINEN LL_USART_EnableLIN
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableLIN(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR2, USART_CR2_LINEN);
+}
+
+/**
+ * @brief Disable LIN mode
+ * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LINEN LL_USART_DisableLIN
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableLIN(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR2, USART_CR2_LINEN);
+}
+
+/**
+ * @brief Indicate if LIN mode is enabled
+ * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LINEN LL_USART_IsEnabledLIN
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledLIN(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR2, USART_CR2_LINEN) == (USART_CR2_LINEN));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_AdvancedConfiguration Advanced Configurations services
+ * @{
+ */
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in Asynchronous Mode (UART)
+ * @note In UART mode, the following bits must be kept cleared:
+ * - LINEN bit in the USART_CR2 register,
+ * - CLKEN bit in the USART_CR2 register,
+ * - SCEN bit in the USART_CR3 register,
+ * - IREN bit in the USART_CR3 register,
+ * - HDSEL bit in the USART_CR3 register.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
+ * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
+ * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
+ * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
+ * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
+ * @note Other remaining configurations items related to Asynchronous Mode
+ * (as Baud Rate, Word length, Parity, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 LINEN LL_USART_ConfigAsyncMode\n
+ * CR2 CLKEN LL_USART_ConfigAsyncMode\n
+ * CR3 SCEN LL_USART_ConfigAsyncMode\n
+ * CR3 IREN LL_USART_ConfigAsyncMode\n
+ * CR3 HDSEL LL_USART_ConfigAsyncMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigAsyncMode(USART_TypeDef *USARTx)
+{
+ /* In Asynchronous mode, the following bits must be kept cleared:
+ - LINEN, CLKEN bits in the USART_CR2 register,
+ - SCEN, IREN and HDSEL bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN | USART_CR3_HDSEL));
+}
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in Synchronous Mode
+ * @note In Synchronous mode, the following bits must be kept cleared:
+ * - LINEN bit in the USART_CR2 register,
+ * - SCEN bit in the USART_CR3 register,
+ * - IREN bit in the USART_CR3 register,
+ * - HDSEL bit in the USART_CR3 register.
+ * This function also sets the USART in Synchronous mode.
+ * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
+ * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
+ * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
+ * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
+ * - Set CLKEN in CR2 using @ref LL_USART_EnableSCLKOutput() function
+ * @note Other remaining configurations items related to Synchronous Mode
+ * (as Baud Rate, Word length, Parity, Clock Polarity, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 LINEN LL_USART_ConfigSyncMode\n
+ * CR2 CLKEN LL_USART_ConfigSyncMode\n
+ * CR3 SCEN LL_USART_ConfigSyncMode\n
+ * CR3 IREN LL_USART_ConfigSyncMode\n
+ * CR3 HDSEL LL_USART_ConfigSyncMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigSyncMode(USART_TypeDef *USARTx)
+{
+ /* In Synchronous mode, the following bits must be kept cleared:
+ - LINEN bit in the USART_CR2 register,
+ - SCEN, IREN and HDSEL bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN | USART_CR3_HDSEL));
+ /* set the UART/USART in Synchronous mode */
+ SET_BIT(USARTx->CR2, USART_CR2_CLKEN);
+}
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in LIN Mode
+ * @note In LIN mode, the following bits must be kept cleared:
+ * - STOP and CLKEN bits in the USART_CR2 register,
+ * - SCEN bit in the USART_CR3 register,
+ * - IREN bit in the USART_CR3 register,
+ * - HDSEL bit in the USART_CR3 register.
+ * This function also set the UART/USART in LIN mode.
+ * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
+ * - Clear STOP in CR2 using @ref LL_USART_SetStopBitsLength() function
+ * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
+ * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
+ * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
+ * - Set LINEN in CR2 using @ref LL_USART_EnableLIN() function
+ * @note Other remaining configurations items related to LIN Mode
+ * (as Baud Rate, Word length, LIN Break Detection Length, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 CLKEN LL_USART_ConfigLINMode\n
+ * CR2 STOP LL_USART_ConfigLINMode\n
+ * CR2 LINEN LL_USART_ConfigLINMode\n
+ * CR3 IREN LL_USART_ConfigLINMode\n
+ * CR3 SCEN LL_USART_ConfigLINMode\n
+ * CR3 HDSEL LL_USART_ConfigLINMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigLINMode(USART_TypeDef *USARTx)
+{
+ /* In LIN mode, the following bits must be kept cleared:
+ - STOP and CLKEN bits in the USART_CR2 register,
+ - IREN, SCEN and HDSEL bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_CLKEN | USART_CR2_STOP));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_SCEN | USART_CR3_HDSEL));
+ /* Set the UART/USART in LIN mode */
+ SET_BIT(USARTx->CR2, USART_CR2_LINEN);
+}
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in Half Duplex Mode
+ * @note In Half Duplex mode, the following bits must be kept cleared:
+ * - LINEN bit in the USART_CR2 register,
+ * - CLKEN bit in the USART_CR2 register,
+ * - SCEN bit in the USART_CR3 register,
+ * - IREN bit in the USART_CR3 register,
+ * This function also sets the UART/USART in Half Duplex mode.
+ * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not
+ * Half-Duplex mode is supported by the USARTx instance.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
+ * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
+ * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
+ * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
+ * - Set HDSEL in CR3 using @ref LL_USART_EnableHalfDuplex() function
+ * @note Other remaining configurations items related to Half Duplex Mode
+ * (as Baud Rate, Word length, Parity, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 LINEN LL_USART_ConfigHalfDuplexMode\n
+ * CR2 CLKEN LL_USART_ConfigHalfDuplexMode\n
+ * CR3 HDSEL LL_USART_ConfigHalfDuplexMode\n
+ * CR3 SCEN LL_USART_ConfigHalfDuplexMode\n
+ * CR3 IREN LL_USART_ConfigHalfDuplexMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigHalfDuplexMode(USART_TypeDef *USARTx)
+{
+ /* In Half Duplex mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN));
+ /* set the UART/USART in Half Duplex mode */
+ SET_BIT(USARTx->CR3, USART_CR3_HDSEL);
+}
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in Smartcard Mode
+ * @note In Smartcard mode, the following bits must be kept cleared:
+ * - LINEN bit in the USART_CR2 register,
+ * - IREN bit in the USART_CR3 register,
+ * - HDSEL bit in the USART_CR3 register.
+ * This function also configures Stop bits to 1.5 bits and
+ * sets the USART in Smartcard mode (SCEN bit).
+ * Clock Output is also enabled (CLKEN).
+ * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
+ * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
+ * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
+ * - Configure STOP in CR2 using @ref LL_USART_SetStopBitsLength() function
+ * - Set CLKEN in CR2 using @ref LL_USART_EnableSCLKOutput() function
+ * - Set SCEN in CR3 using @ref LL_USART_EnableSmartcard() function
+ * @note Other remaining configurations items related to Smartcard Mode
+ * (as Baud Rate, Word length, Parity, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 LINEN LL_USART_ConfigSmartcardMode\n
+ * CR2 STOP LL_USART_ConfigSmartcardMode\n
+ * CR2 CLKEN LL_USART_ConfigSmartcardMode\n
+ * CR3 HDSEL LL_USART_ConfigSmartcardMode\n
+ * CR3 SCEN LL_USART_ConfigSmartcardMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigSmartcardMode(USART_TypeDef *USARTx)
+{
+ /* In Smartcard mode, the following bits must be kept cleared:
+ - LINEN bit in the USART_CR2 register,
+ - IREN and HDSEL bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_HDSEL));
+ /* Configure Stop bits to 1.5 bits */
+ /* Synchronous mode is activated by default */
+ SET_BIT(USARTx->CR2, (USART_CR2_STOP_0 | USART_CR2_STOP_1 | USART_CR2_CLKEN));
+ /* set the UART/USART in Smartcard mode */
+ SET_BIT(USARTx->CR3, USART_CR3_SCEN);
+}
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in Irda Mode
+ * @note In IRDA mode, the following bits must be kept cleared:
+ * - LINEN bit in the USART_CR2 register,
+ * - STOP and CLKEN bits in the USART_CR2 register,
+ * - SCEN bit in the USART_CR3 register,
+ * - HDSEL bit in the USART_CR3 register.
+ * This function also sets the UART/USART in IRDA mode (IREN bit).
+ * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
+ * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
+ * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
+ * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
+ * - Configure STOP in CR2 using @ref LL_USART_SetStopBitsLength() function
+ * - Set IREN in CR3 using @ref LL_USART_EnableIrda() function
+ * @note Other remaining configurations items related to Irda Mode
+ * (as Baud Rate, Word length, Power mode, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 LINEN LL_USART_ConfigIrdaMode\n
+ * CR2 CLKEN LL_USART_ConfigIrdaMode\n
+ * CR2 STOP LL_USART_ConfigIrdaMode\n
+ * CR3 SCEN LL_USART_ConfigIrdaMode\n
+ * CR3 HDSEL LL_USART_ConfigIrdaMode\n
+ * CR3 IREN LL_USART_ConfigIrdaMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigIrdaMode(USART_TypeDef *USARTx)
+{
+ /* In IRDA mode, the following bits must be kept cleared:
+ - LINEN, STOP and CLKEN bits in the USART_CR2 register,
+ - SCEN and HDSEL bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL));
+ /* set the UART/USART in IRDA mode */
+ SET_BIT(USARTx->CR3, USART_CR3_IREN);
+}
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in Multi processor Mode
+ * (several USARTs connected in a network, one of the USARTs can be the master,
+ * its TX output connected to the RX inputs of the other slaves USARTs).
+ * @note In MultiProcessor mode, the following bits must be kept cleared:
+ * - LINEN bit in the USART_CR2 register,
+ * - CLKEN bit in the USART_CR2 register,
+ * - SCEN bit in the USART_CR3 register,
+ * - IREN bit in the USART_CR3 register,
+ * - HDSEL bit in the USART_CR3 register.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
+ * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
+ * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
+ * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
+ * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
+ * @note Other remaining configurations items related to Multi processor Mode
+ * (as Baud Rate, Wake Up Method, Node address, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 LINEN LL_USART_ConfigMultiProcessMode\n
+ * CR2 CLKEN LL_USART_ConfigMultiProcessMode\n
+ * CR3 SCEN LL_USART_ConfigMultiProcessMode\n
+ * CR3 HDSEL LL_USART_ConfigMultiProcessMode\n
+ * CR3 IREN LL_USART_ConfigMultiProcessMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigMultiProcessMode(USART_TypeDef *USARTx)
+{
+ /* In Multi Processor mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - IREN, SCEN and HDSEL bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_FLAG_Management FLAG_Management
+ * @{
+ */
+
+/**
+ * @brief Check if the USART Parity Error Flag is set or not
+ * @rmtoll SR PE LL_USART_IsActiveFlag_PE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_PE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_PE) == (USART_SR_PE));
+}
+
+/**
+ * @brief Check if the USART Framing Error Flag is set or not
+ * @rmtoll SR FE LL_USART_IsActiveFlag_FE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_FE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_FE) == (USART_SR_FE));
+}
+
+/**
+ * @brief Check if the USART Noise error detected Flag is set or not
+ * @rmtoll SR NF LL_USART_IsActiveFlag_NE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_NE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_NE) == (USART_SR_NE));
+}
+
+/**
+ * @brief Check if the USART OverRun Error Flag is set or not
+ * @rmtoll SR ORE LL_USART_IsActiveFlag_ORE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ORE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_ORE) == (USART_SR_ORE));
+}
+
+/**
+ * @brief Check if the USART IDLE line detected Flag is set or not
+ * @rmtoll SR IDLE LL_USART_IsActiveFlag_IDLE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_IDLE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_IDLE) == (USART_SR_IDLE));
+}
+
+/**
+ * @brief Check if the USART Read Data Register Not Empty Flag is set or not
+ * @rmtoll SR RXNE LL_USART_IsActiveFlag_RXNE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RXNE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_RXNE) == (USART_SR_RXNE));
+}
+
+/**
+ * @brief Check if the USART Transmission Complete Flag is set or not
+ * @rmtoll SR TC LL_USART_IsActiveFlag_TC
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TC(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_TC) == (USART_SR_TC));
+}
+
+/**
+ * @brief Check if the USART Transmit Data Register Empty Flag is set or not
+ * @rmtoll SR TXE LL_USART_IsActiveFlag_TXE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TXE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_TXE) == (USART_SR_TXE));
+}
+
+/**
+ * @brief Check if the USART LIN Break Detection Flag is set or not
+ * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll SR LBD LL_USART_IsActiveFlag_LBD
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_LBD(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_LBD) == (USART_SR_LBD));
+}
+
+/**
+ * @brief Check if the USART CTS Flag is set or not
+ * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll SR CTS LL_USART_IsActiveFlag_nCTS
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_nCTS(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_CTS) == (USART_SR_CTS));
+}
+
+/**
+ * @brief Check if the USART Send Break Flag is set or not
+ * @rmtoll CR1 SBK LL_USART_IsActiveFlag_SBK
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_SBK(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_SBK) == (USART_CR1_SBK));
+}
+
+/**
+ * @brief Check if the USART Receive Wake Up from mute mode Flag is set or not
+ * @rmtoll CR1 RWU LL_USART_IsActiveFlag_RWU
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RWU(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_RWU) == (USART_CR1_RWU));
+}
+
+/**
+ * @brief Clear Parity Error Flag
+ * @note Clearing this flag is done by a read access to the USARTx_SR
+ * register followed by a read access to the USARTx_DR register.
+ * @note Please also consider that when clearing this flag, other flags as
+ * NE, FE, ORE, IDLE would also be cleared.
+ * @rmtoll SR PE LL_USART_ClearFlag_PE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_PE(USART_TypeDef *USARTx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = USARTx->SR;
+ (void) tmpreg;
+ tmpreg = USARTx->DR;
+ (void) tmpreg;
+}
+
+/**
+ * @brief Clear Framing Error Flag
+ * @note Clearing this flag is done by a read access to the USARTx_SR
+ * register followed by a read access to the USARTx_DR register.
+ * @note Please also consider that when clearing this flag, other flags as
+ * PE, NE, ORE, IDLE would also be cleared.
+ * @rmtoll SR FE LL_USART_ClearFlag_FE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_FE(USART_TypeDef *USARTx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = USARTx->SR;
+ (void) tmpreg;
+ tmpreg = USARTx->DR;
+ (void) tmpreg;
+}
+
+/**
+ * @brief Clear Noise detected Flag
+ * @note Clearing this flag is done by a read access to the USARTx_SR
+ * register followed by a read access to the USARTx_DR register.
+ * @note Please also consider that when clearing this flag, other flags as
+ * PE, FE, ORE, IDLE would also be cleared.
+ * @rmtoll SR NF LL_USART_ClearFlag_NE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_NE(USART_TypeDef *USARTx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = USARTx->SR;
+ (void) tmpreg;
+ tmpreg = USARTx->DR;
+ (void) tmpreg;
+}
+
+/**
+ * @brief Clear OverRun Error Flag
+ * @note Clearing this flag is done by a read access to the USARTx_SR
+ * register followed by a read access to the USARTx_DR register.
+ * @note Please also consider that when clearing this flag, other flags as
+ * PE, NE, FE, IDLE would also be cleared.
+ * @rmtoll SR ORE LL_USART_ClearFlag_ORE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_ORE(USART_TypeDef *USARTx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = USARTx->SR;
+ (void) tmpreg;
+ tmpreg = USARTx->DR;
+ (void) tmpreg;
+}
+
+/**
+ * @brief Clear IDLE line detected Flag
+ * @note Clearing this flag is done by a read access to the USARTx_SR
+ * register followed by a read access to the USARTx_DR register.
+ * @note Please also consider that when clearing this flag, other flags as
+ * PE, NE, FE, ORE would also be cleared.
+ * @rmtoll SR IDLE LL_USART_ClearFlag_IDLE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_IDLE(USART_TypeDef *USARTx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = USARTx->SR;
+ (void) tmpreg;
+ tmpreg = USARTx->DR;
+ (void) tmpreg;
+}
+
+/**
+ * @brief Clear Transmission Complete Flag
+ * @rmtoll SR TC LL_USART_ClearFlag_TC
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_TC(USART_TypeDef *USARTx)
+{
+ WRITE_REG(USARTx->SR, ~(USART_SR_TC));
+}
+
+/**
+ * @brief Clear RX Not Empty Flag
+ * @rmtoll SR RXNE LL_USART_ClearFlag_RXNE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_RXNE(USART_TypeDef *USARTx)
+{
+ WRITE_REG(USARTx->SR, ~(USART_SR_RXNE));
+}
+
+/**
+ * @brief Clear LIN Break Detection Flag
+ * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll SR LBD LL_USART_ClearFlag_LBD
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_LBD(USART_TypeDef *USARTx)
+{
+ WRITE_REG(USARTx->SR, ~(USART_SR_LBD));
+}
+
+/**
+ * @brief Clear CTS Interrupt Flag
+ * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll SR CTS LL_USART_ClearFlag_nCTS
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_nCTS(USART_TypeDef *USARTx)
+{
+ WRITE_REG(USARTx->SR, ~(USART_SR_CTS));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_IT_Management IT_Management
+ * @{
+ */
+
+/**
+ * @brief Enable IDLE Interrupt
+ * @rmtoll CR1 IDLEIE LL_USART_EnableIT_IDLE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_IDLE(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_IDLEIE);
+}
+
+/**
+ * @brief Enable RX Not Empty Interrupt
+ * @rmtoll CR1 RXNEIE LL_USART_EnableIT_RXNE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_RXNE(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RXNEIE);
+}
+
+/**
+ * @brief Enable Transmission Complete Interrupt
+ * @rmtoll CR1 TCIE LL_USART_EnableIT_TC
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_TC(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TCIE);
+}
+
+/**
+ * @brief Enable TX Empty Interrupt
+ * @rmtoll CR1 TXEIE LL_USART_EnableIT_TXE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_TXE(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TXEIE);
+}
+
+/**
+ * @brief Enable Parity Error Interrupt
+ * @rmtoll CR1 PEIE LL_USART_EnableIT_PE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_PE(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_PEIE);
+}
+
+/**
+ * @brief Enable LIN Break Detection Interrupt
+ * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LBDIE LL_USART_EnableIT_LBD
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_LBD(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR2, USART_CR2_LBDIE);
+}
+
+/**
+ * @brief Enable Error Interrupt
+ * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing
+ * error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the USARTx_SR register).
+ * 0: Interrupt is inhibited
+ * 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the USARTx_SR register.
+ * @rmtoll CR3 EIE LL_USART_EnableIT_ERROR
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_ERROR(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_EIE);
+}
+
+/**
+ * @brief Enable CTS Interrupt
+ * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 CTSIE LL_USART_EnableIT_CTS
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_CTS(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_CTSIE);
+}
+
+/**
+ * @brief Disable IDLE Interrupt
+ * @rmtoll CR1 IDLEIE LL_USART_DisableIT_IDLE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_IDLE(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_IDLEIE);
+}
+
+/**
+ * @brief Disable RX Not Empty Interrupt
+ * @rmtoll CR1 RXNEIE LL_USART_DisableIT_RXNE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_RXNE(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RXNEIE);
+}
+
+/**
+ * @brief Disable Transmission Complete Interrupt
+ * @rmtoll CR1 TCIE LL_USART_DisableIT_TC
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_TC(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TCIE);
+}
+
+/**
+ * @brief Disable TX Empty Interrupt
+ * @rmtoll CR1 TXEIE LL_USART_DisableIT_TXE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_TXE(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TXEIE);
+}
+
+/**
+ * @brief Disable Parity Error Interrupt
+ * @rmtoll CR1 PEIE LL_USART_DisableIT_PE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_PE(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_PEIE);
+}
+
+/**
+ * @brief Disable LIN Break Detection Interrupt
+ * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LBDIE LL_USART_DisableIT_LBD
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_LBD(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR2, USART_CR2_LBDIE);
+}
+
+/**
+ * @brief Disable Error Interrupt
+ * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing
+ * error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the USARTx_SR register).
+ * 0: Interrupt is inhibited
+ * 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the USARTx_SR register.
+ * @rmtoll CR3 EIE LL_USART_DisableIT_ERROR
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_ERROR(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_EIE);
+}
+
+/**
+ * @brief Disable CTS Interrupt
+ * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 CTSIE LL_USART_DisableIT_CTS
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_CTS(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_CTSIE);
+}
+
+/**
+ * @brief Check if the USART IDLE Interrupt source is enabled or disabled.
+ * @rmtoll CR1 IDLEIE LL_USART_IsEnabledIT_IDLE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_IDLE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_IDLEIE) == (USART_CR1_IDLEIE));
+}
+
+/**
+ * @brief Check if the USART RX Not Empty Interrupt is enabled or disabled.
+ * @rmtoll CR1 RXNEIE LL_USART_IsEnabledIT_RXNE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RXNE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_RXNEIE) == (USART_CR1_RXNEIE));
+}
+
+/**
+ * @brief Check if the USART Transmission Complete Interrupt is enabled or disabled.
+ * @rmtoll CR1 TCIE LL_USART_IsEnabledIT_TC
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TC(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_TCIE) == (USART_CR1_TCIE));
+}
+
+/**
+ * @brief Check if the USART TX Empty Interrupt is enabled or disabled.
+ * @rmtoll CR1 TXEIE LL_USART_IsEnabledIT_TXE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TXE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_TXEIE) == (USART_CR1_TXEIE));
+}
+
+/**
+ * @brief Check if the USART Parity Error Interrupt is enabled or disabled.
+ * @rmtoll CR1 PEIE LL_USART_IsEnabledIT_PE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_PE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_PEIE) == (USART_CR1_PEIE));
+}
+
+/**
+ * @brief Check if the USART LIN Break Detection Interrupt is enabled or disabled.
+ * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LBDIE LL_USART_IsEnabledIT_LBD
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_LBD(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR2, USART_CR2_LBDIE) == (USART_CR2_LBDIE));
+}
+
+/**
+ * @brief Check if the USART Error Interrupt is enabled or disabled.
+ * @rmtoll CR3 EIE LL_USART_IsEnabledIT_ERROR
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_ERROR(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_EIE) == (USART_CR3_EIE));
+}
+
+/**
+ * @brief Check if the USART CTS Interrupt is enabled or disabled.
+ * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 CTSIE LL_USART_IsEnabledIT_CTS
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_CTS(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_CTSIE) == (USART_CR3_CTSIE));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_DMA_Management DMA_Management
+ * @{
+ */
+
+/**
+ * @brief Enable DMA Mode for reception
+ * @rmtoll CR3 DMAR LL_USART_EnableDMAReq_RX
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableDMAReq_RX(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_DMAR);
+}
+
+/**
+ * @brief Disable DMA Mode for reception
+ * @rmtoll CR3 DMAR LL_USART_DisableDMAReq_RX
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableDMAReq_RX(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_DMAR);
+}
+
+/**
+ * @brief Check if DMA Mode is enabled for reception
+ * @rmtoll CR3 DMAR LL_USART_IsEnabledDMAReq_RX
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledDMAReq_RX(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_DMAR) == (USART_CR3_DMAR));
+}
+
+/**
+ * @brief Enable DMA Mode for transmission
+ * @rmtoll CR3 DMAT LL_USART_EnableDMAReq_TX
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableDMAReq_TX(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_DMAT);
+}
+
+/**
+ * @brief Disable DMA Mode for transmission
+ * @rmtoll CR3 DMAT LL_USART_DisableDMAReq_TX
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableDMAReq_TX(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_DMAT);
+}
+
+/**
+ * @brief Check if DMA Mode is enabled for transmission
+ * @rmtoll CR3 DMAT LL_USART_IsEnabledDMAReq_TX
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledDMAReq_TX(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_DMAT) == (USART_CR3_DMAT));
+}
+
+/**
+ * @brief Get the data register address used for DMA transfer
+ * @rmtoll DR DR LL_USART_DMA_GetRegAddr
+ * @note Address of Data Register is valid for both Transmit and Receive transfers.
+ * @param USARTx USART Instance
+ * @retval Address of data register
+ */
+__STATIC_INLINE uint32_t LL_USART_DMA_GetRegAddr(const USART_TypeDef *USARTx)
+{
+ /* return address of DR register */
+ return ((uint32_t) &(USARTx->DR));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_Data_Management Data_Management
+ * @{
+ */
+
+/**
+ * @brief Read Receiver Data register (Receive Data value, 8 bits)
+ * @rmtoll DR DR LL_USART_ReceiveData8
+ * @param USARTx USART Instance
+ * @retval Value between Min_Data=0x00 and Max_Data=0xFF
+ */
+__STATIC_INLINE uint8_t LL_USART_ReceiveData8(const USART_TypeDef *USARTx)
+{
+ return (uint8_t)(READ_BIT(USARTx->DR, USART_DR_DR));
+}
+
+/**
+ * @brief Read Receiver Data register (Receive Data value, 9 bits)
+ * @rmtoll DR DR LL_USART_ReceiveData9
+ * @param USARTx USART Instance
+ * @retval Value between Min_Data=0x00 and Max_Data=0x1FF
+ */
+__STATIC_INLINE uint16_t LL_USART_ReceiveData9(const USART_TypeDef *USARTx)
+{
+ return (uint16_t)(READ_BIT(USARTx->DR, USART_DR_DR));
+}
+
+/**
+ * @brief Write in Transmitter Data Register (Transmit Data value, 8 bits)
+ * @rmtoll DR DR LL_USART_TransmitData8
+ * @param USARTx USART Instance
+ * @param Value between Min_Data=0x00 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_TransmitData8(USART_TypeDef *USARTx, uint8_t Value)
+{
+ USARTx->DR = Value;
+}
+
+/**
+ * @brief Write in Transmitter Data Register (Transmit Data value, 9 bits)
+ * @rmtoll DR DR LL_USART_TransmitData9
+ * @param USARTx USART Instance
+ * @param Value between Min_Data=0x00 and Max_Data=0x1FF
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_TransmitData9(USART_TypeDef *USARTx, uint16_t Value)
+{
+ USARTx->DR = Value & 0x1FFU;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_Execution Execution
+ * @{
+ */
+
+/**
+ * @brief Request Break sending
+ * @rmtoll CR1 SBK LL_USART_RequestBreakSending
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_RequestBreakSending(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR1, USART_CR1_SBK);
+}
+
+/**
+ * @brief Put USART in Mute mode
+ * @rmtoll CR1 RWU LL_USART_RequestEnterMuteMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_RequestEnterMuteMode(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR1, USART_CR1_RWU);
+}
+
+/**
+ * @brief Put USART in Active mode
+ * @rmtoll CR1 RWU LL_USART_RequestExitMuteMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_RequestExitMuteMode(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR1, USART_CR1_RWU);
+}
+
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup USART_LL_EF_Init Initialization and de-initialization functions
+ * @{
+ */
+ErrorStatus LL_USART_DeInit(const USART_TypeDef *USARTx);
+ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, const LL_USART_InitTypeDef *USART_InitStruct);
+void LL_USART_StructInit(LL_USART_InitTypeDef *USART_InitStruct);
+ErrorStatus LL_USART_ClockInit(USART_TypeDef *USARTx, const LL_USART_ClockInitTypeDef *USART_ClockInitStruct);
+void LL_USART_ClockStructInit(LL_USART_ClockInitTypeDef *USART_ClockInitStruct);
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* USART1 || USART2 || USART3 || USART6 || UART4 || UART5 || UART7 || UART8 || UART9 || UART10 */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_LL_USART_H */
+
diff --git a/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c b/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c
new file mode 100644
index 0000000..df22cad
--- /dev/null
+++ b/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c
@@ -0,0 +1,2395 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_nand.c
+ * @author MCD Application Team
+ * @brief NAND HAL module driver.
+ * This file provides a generic firmware to drive NAND memories mounted
+ * as external device.
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver is a generic layered driver which contains a set of APIs used to
+ control NAND flash memories. It uses the FMC/FSMC layer functions to interface
+ with NAND devices. This driver is used as follows:
+
+ (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
+ with control and timing parameters for both common and attribute spaces.
+
+ (+) Read NAND flash memory maker and device IDs using the function
+ HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
+ structure declared by the function caller.
+
+ (+) Access NAND flash memory by read/write operations using the functions
+ HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(),
+ HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
+ HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
+ HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
+ to read/write page(s)/spare area(s). These functions use specific device
+ information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
+ structure. The read/write address information is contained by the Nand_Address_Typedef
+ structure passed as parameter.
+
+ (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
+
+ (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
+ The erase block address information is contained in the Nand_Address_Typedef
+ structure passed as parameter.
+
+ (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
+
+ (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
+ HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
+ feature or the function HAL_NAND_GetECC() to get the ECC correction code.
+
+ (+) You can monitor the NAND device HAL state by calling the function
+ HAL_NAND_GetState()
+
+ [..]
+ (@) This driver is a set of generic APIs which handle standard NAND flash operations.
+ If a NAND flash device contains different operations and/or implementations,
+ it should be implemented separately.
+
+ *** Callback registration ***
+ =============================================
+ [..]
+ The compilation define USE_HAL_NAND_REGISTER_CALLBACKS when set to 1
+ allows the user to configure dynamically the driver callbacks.
+
+ Use Functions HAL_NAND_RegisterCallback() to register a user callback,
+ it allows to register following callbacks:
+ (+) MspInitCallback : NAND MspInit.
+ (+) MspDeInitCallback : NAND MspDeInit.
+ This function takes as parameters the HAL peripheral handle, the Callback ID
+ and a pointer to the user callback function.
+
+ Use function HAL_NAND_UnRegisterCallback() to reset a callback to the default
+ weak (overridden) function. It allows to reset following callbacks:
+ (+) MspInitCallback : NAND MspInit.
+ (+) MspDeInitCallback : NAND MspDeInit.
+ This function) takes as parameters the HAL peripheral handle and the Callback ID.
+
+ By default, after the HAL_NAND_Init and if the state is HAL_NAND_STATE_RESET
+ all callbacks are reset to the corresponding legacy weak (overridden) functions.
+ Exception done for MspInit and MspDeInit callbacks that are respectively
+ reset to the legacy weak (overridden) functions in the HAL_NAND_Init
+ and HAL_NAND_DeInit only when these callbacks are null (not registered beforehand).
+ If not, MspInit or MspDeInit are not null, the HAL_NAND_Init and HAL_NAND_DeInit
+ keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
+
+ Callbacks can be registered/unregistered in READY state only.
+ Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
+ in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
+ during the Init/DeInit.
+ In that case first register the MspInit/MspDeInit user callbacks
+ using HAL_NAND_RegisterCallback before calling HAL_NAND_DeInit
+ or HAL_NAND_Init function.
+
+ When The compilation define USE_HAL_NAND_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registering feature is not available
+ and weak (overridden) callbacks are used.
+
+ @endverbatim
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+#if defined(FMC_Bank3) || defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+
+/** @defgroup NAND NAND
+ * @brief NAND HAL module driver
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private Constants ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup NAND_Exported_Functions NAND Exported Functions
+ * @{
+ */
+
+/** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### NAND Initialization and de-initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to initialize/de-initialize
+ the NAND memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Perform NAND memory Initialization sequence
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param ComSpace_Timing pointer to Common space timing structure
+ * @param AttSpace_Timing pointer to Attribute space timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing,
+ FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
+{
+ /* Check the NAND handle state */
+ if (hnand == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (hnand->State == HAL_NAND_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hnand->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
+ if (hnand->MspInitCallback == NULL)
+ {
+ hnand->MspInitCallback = HAL_NAND_MspInit;
+ }
+ hnand->ItCallback = HAL_NAND_ITCallback;
+
+ /* Init the low level hardware */
+ hnand->MspInitCallback(hnand);
+#else
+ /* Initialize the low level hardware (MSP) */
+ HAL_NAND_MspInit(hnand);
+#endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
+ }
+
+ /* Initialize NAND control Interface */
+ (void)FMC_NAND_Init(hnand->Instance, &(hnand->Init));
+
+ /* Initialize NAND common space timing Interface */
+ (void)FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
+
+ /* Initialize NAND attribute space timing Interface */
+ (void)FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
+
+ /* Enable the NAND device */
+#if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
+ __FMC_NAND_ENABLE(hnand->Instance, hnand->Init.NandBank);
+#else
+ __FMC_NAND_ENABLE(hnand->Instance);
+#endif /* (FMC_Bank2_3) || (FSMC_Bank2_3) */
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Perform NAND memory De-Initialization sequence
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
+{
+#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
+ if (hnand->MspDeInitCallback == NULL)
+ {
+ hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
+ }
+
+ /* DeInit the low level hardware */
+ hnand->MspDeInitCallback(hnand);
+#else
+ /* Initialize the low level hardware (MSP) */
+ HAL_NAND_MspDeInit(hnand);
+#endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
+
+ /* Configure the NAND registers with their reset values */
+ (void)FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
+
+ /* Reset the NAND controller state */
+ hnand->State = HAL_NAND_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief NAND MSP Init
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval None
+ */
+__weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hnand);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_NAND_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief NAND MSP DeInit
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval None
+ */
+__weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hnand);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_NAND_MspDeInit could be implemented in the user file
+ */
+}
+
+
+/**
+ * @brief This function handles NAND device interrupt request.
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval HAL status
+ */
+void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
+{
+ /* Check NAND interrupt Rising edge flag */
+ if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
+ {
+ /* NAND interrupt callback*/
+#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
+ hnand->ItCallback(hnand);
+#else
+ HAL_NAND_ITCallback(hnand);
+#endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
+
+ /* Clear NAND interrupt Rising edge pending bit */
+#if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
+ __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE);
+#else
+ __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
+#endif /* FMC_Bank2_3 || FSMC_Bank2_3 */
+ }
+
+ /* Check NAND interrupt Level flag */
+ if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
+ {
+ /* NAND interrupt callback*/
+#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
+ hnand->ItCallback(hnand);
+#else
+ HAL_NAND_ITCallback(hnand);
+#endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
+
+ /* Clear NAND interrupt Level pending bit */
+#if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
+ __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL);
+#else
+ __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
+#endif /* FMC_Bank2_3 || FSMC_Bank2_3 */
+ }
+
+ /* Check NAND interrupt Falling edge flag */
+ if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
+ {
+ /* NAND interrupt callback*/
+#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
+ hnand->ItCallback(hnand);
+#else
+ HAL_NAND_ITCallback(hnand);
+#endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
+
+ /* Clear NAND interrupt Falling edge pending bit */
+#if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
+ __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE);
+#else
+ __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
+#endif /* FMC_Bank2_3 || FSMC_Bank2_3 */
+ }
+
+ /* Check NAND interrupt FIFO empty flag */
+ if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
+ {
+ /* NAND interrupt callback*/
+#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
+ hnand->ItCallback(hnand);
+#else
+ HAL_NAND_ITCallback(hnand);
+#endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
+
+ /* Clear NAND interrupt FIFO empty pending bit */
+#if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
+ __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT);
+#else
+ __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
+#endif /* FMC_Bank2_3 || FSMC_Bank2_3 */
+ }
+
+}
+
+/**
+ * @brief NAND interrupt feature callback
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval None
+ */
+__weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hnand);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_NAND_ITCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
+ * @brief Input Output and memory control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### NAND Input and Output functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to use and control the NAND
+ memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Read the NAND memory electronic signature
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pNAND_ID NAND ID structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
+{
+ __IO uint32_t data = 0;
+ __IO uint32_t data1 = 0;
+ uint32_t deviceaddress;
+
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Identify the device address */
+#if defined(FMC_Bank2_3)
+ if (hnand->Init.NandBank == FMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+#else
+ deviceaddress = NAND_DEVICE;
+#endif /* FMC_Bank2_3 */
+
+ /* Send Read ID command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_READID;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ __DSB();
+
+ /* Read the electronic signature from NAND flash */
+#ifdef FSMC_PCR2_PWID
+ if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
+#else /* FMC_PCR2_PWID is defined */
+ if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8)
+#endif /* FSMC_PCR2_PWID */
+ {
+ data = *(__IO uint32_t *)deviceaddress;
+
+ /* Return the data read */
+ pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
+ pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data);
+ pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data);
+ pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data);
+ }
+ else
+ {
+ data = *(__IO uint32_t *)deviceaddress;
+ data1 = *((__IO uint32_t *)deviceaddress + 4);
+
+ /* Return the data read */
+ pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
+ pNAND_ID->Device_Id = ADDR_3RD_CYCLE(data);
+ pNAND_ID->Third_Id = ADDR_1ST_CYCLE(data1);
+ pNAND_ID->Fourth_Id = ADDR_3RD_CYCLE(data1);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief NAND memory reset
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
+{
+ uint32_t deviceaddress;
+
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Identify the device address */
+#if defined(FMC_Bank2_3)
+ if (hnand->Init.NandBank == FMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+#else
+ deviceaddress = NAND_DEVICE;
+#endif /* FMC_Bank2_3 */
+
+ /* Send NAND reset command */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+
+}
+
+/**
+ * @brief Configure the device: Enter the physical parameters of the device
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pDeviceConfig pointer to NAND_DeviceConfigTypeDef structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, const NAND_DeviceConfigTypeDef *pDeviceConfig)
+{
+ hnand->Config.PageSize = pDeviceConfig->PageSize;
+ hnand->Config.SpareAreaSize = pDeviceConfig->SpareAreaSize;
+ hnand->Config.BlockSize = pDeviceConfig->BlockSize;
+ hnand->Config.BlockNbr = pDeviceConfig->BlockNbr;
+ hnand->Config.PlaneSize = pDeviceConfig->PlaneSize;
+ hnand->Config.PlaneNbr = pDeviceConfig->PlaneNbr;
+ hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read Page(s) from NAND memory block (8-bits addressing)
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress pointer to NAND address structure
+ * @param pBuffer pointer to destination read buffer
+ * @param NumPageToRead number of pages to read from block
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ uint8_t *pBuffer, uint32_t NumPageToRead)
+{
+ uint32_t index;
+ uint32_t tickstart;
+ uint32_t deviceaddress;
+ uint32_t numpagesread = 0U;
+ uint32_t nandaddress;
+ uint32_t nbpages = NumPageToRead;
+ uint8_t *buff = pBuffer;
+
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Identify the device address */
+#if defined(FMC_Bank2_3)
+ if (hnand->Init.NandBank == FMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+#else
+ deviceaddress = NAND_DEVICE;
+#endif /* FMC_Bank2_3 */
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Page(s) read loop */
+ while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* Send read page command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+ __DSB();
+
+ /* Cards with page size <= 512 bytes */
+ if ((hnand->Config.PageSize) <= 512U)
+ {
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
+ __DSB();
+
+
+ if (hnand->Config.ExtraCommandEnable == ENABLE)
+ {
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while (HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
+ {
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_ERROR;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Go back to read mode */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
+ __DSB();
+ }
+
+ /* Get Data into Buffer */
+ for (index = 0U; index < hnand->Config.PageSize; index++)
+ {
+ *buff = *(__IO uint8_t *)deviceaddress;
+ buff++;
+ }
+
+ /* Increment read pages number */
+ numpagesread++;
+
+ /* Decrement pages to read */
+ nbpages--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read Page(s) from NAND memory block (16-bits addressing)
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress pointer to NAND address structure
+ * @param pBuffer pointer to destination read buffer. pBuffer should be 16bits aligned
+ * @param NumPageToRead number of pages to read from block
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ uint16_t *pBuffer, uint32_t NumPageToRead)
+{
+ uint32_t index;
+ uint32_t tickstart;
+ uint32_t deviceaddress;
+ uint32_t numpagesread = 0U;
+ uint32_t nandaddress;
+ uint32_t nbpages = NumPageToRead;
+ uint16_t *buff = pBuffer;
+
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Identify the device address */
+#if defined(FMC_Bank2_3)
+ if (hnand->Init.NandBank == FMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+#else
+ deviceaddress = NAND_DEVICE;
+#endif /* FMC_Bank2_3 */
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Page(s) read loop */
+ while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* Send read page command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+ __DSB();
+
+ /* Cards with page size <= 512 bytes */
+ if ((hnand->Config.PageSize) <= 512U)
+ {
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
+ __DSB();
+
+ if (hnand->Config.ExtraCommandEnable == ENABLE)
+ {
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while (HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
+ {
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_ERROR;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Go back to read mode */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
+ __DSB();
+ }
+
+ /* Calculate PageSize */
+#if defined(FSMC_PCR2_PWID)
+ if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
+#else
+ if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8)
+#endif /* FSMC_PCR2_PWID */
+ {
+ hnand->Config.PageSize = hnand->Config.PageSize / 2U;
+ }
+ else
+ {
+ /* Do nothing */
+ /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
+ }
+
+ /* Get Data into Buffer */
+ for (index = 0U; index < hnand->Config.PageSize; index++)
+ {
+ *buff = *(__IO uint16_t *)deviceaddress;
+ buff++;
+ }
+
+ /* Increment read pages number */
+ numpagesread++;
+
+ /* Decrement pages to read */
+ nbpages--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Write Page(s) to NAND memory block (8-bits addressing)
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress pointer to NAND address structure
+ * @param pBuffer pointer to source buffer to write
+ * @param NumPageToWrite number of pages to write to block
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ const uint8_t *pBuffer, uint32_t NumPageToWrite)
+{
+ uint32_t index;
+ uint32_t tickstart;
+ uint32_t deviceaddress;
+ uint32_t numpageswritten = 0U;
+ uint32_t nandaddress;
+ uint32_t nbpages = NumPageToWrite;
+ const uint8_t *buff = pBuffer;
+
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Identify the device address */
+#if defined(FMC_Bank2_3)
+ if (hnand->Init.NandBank == FMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+#else
+ deviceaddress = NAND_DEVICE;
+#endif /* FMC_Bank2_3 */
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Page(s) write loop */
+ while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* Send write page command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
+ __DSB();
+
+ /* Cards with page size <= 512 bytes */
+ if ((hnand->Config.PageSize) <= 512U)
+ {
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+
+ /* Write data to memory */
+ for (index = 0U; index < hnand->Config.PageSize; index++)
+ {
+ *(__IO uint8_t *)deviceaddress = *buff;
+ buff++;
+ __DSB();
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
+ __DSB();
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while (HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
+ {
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_ERROR;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Increment written pages number */
+ numpageswritten++;
+
+ /* Decrement pages to write */
+ nbpages--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Write Page(s) to NAND memory block (16-bits addressing)
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress pointer to NAND address structure
+ * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned
+ * @param NumPageToWrite number of pages to write to block
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ const uint16_t *pBuffer, uint32_t NumPageToWrite)
+{
+ uint32_t index;
+ uint32_t tickstart;
+ uint32_t deviceaddress;
+ uint32_t numpageswritten = 0U;
+ uint32_t nandaddress;
+ uint32_t nbpages = NumPageToWrite;
+ const uint16_t *buff = pBuffer;
+
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Identify the device address */
+#if defined(FMC_Bank2_3)
+ if (hnand->Init.NandBank == FMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+#else
+ deviceaddress = NAND_DEVICE;
+#endif /* FMC_Bank2_3 */
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Page(s) write loop */
+ while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* Send write page command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
+ __DSB();
+
+ /* Cards with page size <= 512 bytes */
+ if ((hnand->Config.PageSize) <= 512U)
+ {
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+
+ /* Calculate PageSize */
+#if defined(FSMC_PCR2_PWID)
+ if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
+#else
+ if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8)
+#endif /* FSMC_PCR2_PWID */
+ {
+ hnand->Config.PageSize = hnand->Config.PageSize / 2U;
+ }
+ else
+ {
+ /* Do nothing */
+ /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
+ }
+
+ /* Write data to memory */
+ for (index = 0U; index < hnand->Config.PageSize; index++)
+ {
+ *(__IO uint16_t *)deviceaddress = *buff;
+ buff++;
+ __DSB();
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
+ __DSB();
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while (HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
+ {
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_ERROR;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Increment written pages number */
+ numpageswritten++;
+
+ /* Decrement pages to write */
+ nbpages--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read Spare area(s) from NAND memory (8-bits addressing)
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress pointer to NAND address structure
+ * @param pBuffer pointer to source buffer to write
+ * @param NumSpareAreaToRead Number of spare area to read
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
+{
+ uint32_t index;
+ uint32_t tickstart;
+ uint32_t deviceaddress;
+ uint32_t numsparearearead = 0U;
+ uint32_t nandaddress;
+ uint32_t columnaddress;
+ uint32_t nbspare = NumSpareAreaToRead;
+ uint8_t *buff = pBuffer;
+
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Identify the device address */
+#if defined(FMC_Bank2_3)
+ if (hnand->Init.NandBank == FMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+#else
+ deviceaddress = NAND_DEVICE;
+#endif /* FMC_Bank2_3 */
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Column in page address */
+ columnaddress = COLUMN_ADDRESS(hnand);
+
+ /* Spare area(s) read loop */
+ while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* Cards with page size <= 512 bytes */
+ if ((hnand->Config.PageSize) <= 512U)
+ {
+ /* Send read spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
+ __DSB();
+
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ /* Send read spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+ __DSB();
+
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
+ __DSB();
+
+ if (hnand->Config.ExtraCommandEnable == ENABLE)
+ {
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while (HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
+ {
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_ERROR;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Go back to read mode */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
+ __DSB();
+ }
+
+ /* Get Data into Buffer */
+ for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
+ {
+ *buff = *(__IO uint8_t *)deviceaddress;
+ buff++;
+ }
+
+ /* Increment read spare areas number */
+ numsparearearead++;
+
+ /* Decrement spare areas to read */
+ nbspare--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read Spare area(s) from NAND memory (16-bits addressing)
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress pointer to NAND address structure
+ * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
+ * @param NumSpareAreaToRead Number of spare area to read
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
+{
+ uint32_t index;
+ uint32_t tickstart;
+ uint32_t deviceaddress;
+ uint32_t numsparearearead = 0U;
+ uint32_t nandaddress;
+ uint32_t columnaddress;
+ uint32_t nbspare = NumSpareAreaToRead;
+ uint16_t *buff = pBuffer;
+
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Identify the device address */
+#if defined(FMC_Bank2_3)
+ if (hnand->Init.NandBank == FMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+#else
+ deviceaddress = NAND_DEVICE;
+#endif /* FMC_Bank2_3 */
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Column in page address */
+ columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
+
+ /* Spare area(s) read loop */
+ while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* Cards with page size <= 512 bytes */
+ if ((hnand->Config.PageSize) <= 512U)
+ {
+ /* Send read spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
+ __DSB();
+
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ /* Send read spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+ __DSB();
+
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
+ __DSB();
+
+ if (hnand->Config.ExtraCommandEnable == ENABLE)
+ {
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while (HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
+ {
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_ERROR;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Go back to read mode */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
+ __DSB();
+ }
+
+ /* Get Data into Buffer */
+ for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
+ {
+ *buff = *(__IO uint16_t *)deviceaddress;
+ buff++;
+ }
+
+ /* Increment read spare areas number */
+ numsparearearead++;
+
+ /* Decrement spare areas to read */
+ nbspare--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Write Spare area(s) to NAND memory (8-bits addressing)
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress pointer to NAND address structure
+ * @param pBuffer pointer to source buffer to write
+ * @param NumSpareAreaTowrite number of spare areas to write to block
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ const uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
+{
+ uint32_t index;
+ uint32_t tickstart;
+ uint32_t deviceaddress;
+ uint32_t numspareareawritten = 0U;
+ uint32_t nandaddress;
+ uint32_t columnaddress;
+ uint32_t nbspare = NumSpareAreaTowrite;
+ const uint8_t *buff = pBuffer;
+
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Identify the device address */
+#if defined(FMC_Bank2_3)
+ if (hnand->Init.NandBank == FMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+#else
+ deviceaddress = NAND_DEVICE;
+#endif /* FMC_Bank2_3 */
+
+ /* Page address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Column in page address */
+ columnaddress = COLUMN_ADDRESS(hnand);
+
+ /* Spare area(s) write loop */
+ while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* Cards with page size <= 512 bytes */
+ if ((hnand->Config.PageSize) <= 512U)
+ {
+ /* Send write Spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
+ __DSB();
+
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ /* Send write Spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
+ __DSB();
+
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+
+ /* Write data to memory */
+ for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
+ {
+ *(__IO uint8_t *)deviceaddress = *buff;
+ buff++;
+ __DSB();
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
+ __DSB();
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while (HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
+ {
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_ERROR;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Increment written spare areas number */
+ numspareareawritten++;
+
+ /* Decrement spare areas to write */
+ nbspare--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Write Spare area(s) to NAND memory (16-bits addressing)
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress pointer to NAND address structure
+ * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
+ * @param NumSpareAreaTowrite number of spare areas to write to block
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
+ const uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
+{
+ uint32_t index;
+ uint32_t tickstart;
+ uint32_t deviceaddress;
+ uint32_t numspareareawritten = 0U;
+ uint32_t nandaddress;
+ uint32_t columnaddress;
+ uint32_t nbspare = NumSpareAreaTowrite;
+ const uint16_t *buff = pBuffer;
+
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Identify the device address */
+#if defined(FMC_Bank2_3)
+ if (hnand->Init.NandBank == FMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+#else
+ deviceaddress = NAND_DEVICE;
+#endif /* FMC_Bank2_3 */
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Column in page address */
+ columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
+
+ /* Spare area(s) write loop */
+ while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* Cards with page size <= 512 bytes */
+ if ((hnand->Config.PageSize) <= 512U)
+ {
+ /* Send write Spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
+ __DSB();
+
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ /* Send write Spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
+ __DSB();
+
+ if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ __DSB();
+ }
+ }
+
+ /* Write data to memory */
+ for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
+ {
+ *(__IO uint16_t *)deviceaddress = *buff;
+ buff++;
+ __DSB();
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
+ __DSB();
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while (HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
+ {
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_ERROR;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Increment written spare areas number */
+ numspareareawritten++;
+
+ /* Decrement spare areas to write */
+ nbspare--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief NAND memory Block erase
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress pointer to NAND address structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress)
+{
+ uint32_t deviceaddress;
+
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Identify the device address */
+#if defined(FMC_Bank2_3)
+ if (hnand->Init.NandBank == FMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+#else
+ deviceaddress = NAND_DEVICE;
+#endif /* FMC_Bank2_3 */
+
+ /* Send Erase block command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
+ __DSB();
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
+ __DSB();
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
+ __DSB();
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Increment the NAND memory address
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress pointer to NAND address structure
+ * @retval The new status of the increment address operation. It can be:
+ * - NAND_VALID_ADDRESS: When the new address is valid address
+ * - NAND_INVALID_ADDRESS: When the new address is invalid address
+ */
+uint32_t HAL_NAND_Address_Inc(const NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
+{
+ uint32_t status = NAND_VALID_ADDRESS;
+
+ /* Increment page address */
+ pAddress->Page++;
+
+ /* Check NAND address is valid */
+ if (pAddress->Page == hnand->Config.BlockSize)
+ {
+ pAddress->Page = 0;
+ pAddress->Block++;
+
+ if (pAddress->Block == hnand->Config.PlaneSize)
+ {
+ pAddress->Block = 0;
+ pAddress->Plane++;
+
+ if (pAddress->Plane == (hnand->Config.PlaneNbr))
+ {
+ status = NAND_INVALID_ADDRESS;
+ }
+ }
+ }
+
+ return (status);
+}
+
+#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
+/**
+ * @brief Register a User NAND Callback
+ * To be used to override the weak predefined callback
+ * @param hnand : NAND handle
+ * @param CallbackId : ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID
+ * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID
+ * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID
+ * @param pCallback : pointer to the Callback function
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_NAND_RegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId,
+ pNAND_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ switch (CallbackId)
+ {
+ case HAL_NAND_MSP_INIT_CB_ID :
+ hnand->MspInitCallback = pCallback;
+ break;
+ case HAL_NAND_MSP_DEINIT_CB_ID :
+ hnand->MspDeInitCallback = pCallback;
+ break;
+ case HAL_NAND_IT_CB_ID :
+ hnand->ItCallback = pCallback;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (hnand->State == HAL_NAND_STATE_RESET)
+ {
+ switch (CallbackId)
+ {
+ case HAL_NAND_MSP_INIT_CB_ID :
+ hnand->MspInitCallback = pCallback;
+ break;
+ case HAL_NAND_MSP_DEINIT_CB_ID :
+ hnand->MspDeInitCallback = pCallback;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* update return status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Unregister a User NAND Callback
+ * NAND Callback is redirected to the weak predefined callback
+ * @param hnand : NAND handle
+ * @param CallbackId : ID of the callback to be unregistered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID
+ * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID
+ * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ switch (CallbackId)
+ {
+ case HAL_NAND_MSP_INIT_CB_ID :
+ hnand->MspInitCallback = HAL_NAND_MspInit;
+ break;
+ case HAL_NAND_MSP_DEINIT_CB_ID :
+ hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
+ break;
+ case HAL_NAND_IT_CB_ID :
+ hnand->ItCallback = HAL_NAND_ITCallback;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (hnand->State == HAL_NAND_STATE_RESET)
+ {
+ switch (CallbackId)
+ {
+ case HAL_NAND_MSP_INIT_CB_ID :
+ hnand->MspInitCallback = HAL_NAND_MspInit;
+ break;
+ case HAL_NAND_MSP_DEINIT_CB_ID :
+ hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* update return status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+#endif /* USE_HAL_NAND_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### NAND Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the NAND interface.
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Enables dynamically NAND ECC feature.
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
+{
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Update the NAND state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Enable ECC feature */
+ (void)FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
+
+ /* Update the NAND state */
+ hnand->State = HAL_NAND_STATE_READY;
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FMC_NAND ECC feature.
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
+{
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Update the NAND state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Disable ECC feature */
+ (void)FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
+
+ /* Update the NAND state */
+ hnand->State = HAL_NAND_STATE_READY;
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically NAND ECC feature.
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param ECCval pointer to ECC value
+ * @param Timeout maximum timeout to wait
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
+{
+ HAL_StatusTypeDef status;
+
+ /* Check the NAND controller state */
+ if (hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnand->State == HAL_NAND_STATE_READY)
+ {
+ /* Update the NAND state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Get NAND ECC value */
+ status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
+
+ /* Update the NAND state */
+ hnand->State = HAL_NAND_STATE_READY;
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### NAND State functions #####
+ ==============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the NAND controller
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief return the NAND state
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval HAL state
+ */
+HAL_NAND_StateTypeDef HAL_NAND_GetState(const NAND_HandleTypeDef *hnand)
+{
+ return hnand->State;
+}
+
+/**
+ * @brief NAND memory read status
+ * @param hnand pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval NAND status
+ */
+uint32_t HAL_NAND_Read_Status(const NAND_HandleTypeDef *hnand)
+{
+ uint32_t data;
+ uint32_t deviceaddress;
+ UNUSED(hnand);
+
+ /* Identify the device address */
+#if defined(FMC_Bank2_3)
+ if (hnand->Init.NandBank == FMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+#else
+ deviceaddress = NAND_DEVICE;
+#endif /* FMC_Bank2_3 */
+
+ /* Send Read status operation command */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
+
+ /* Read status register data */
+ data = *(__IO uint8_t *)deviceaddress;
+
+ /* Return the status */
+ if ((data & NAND_ERROR) == NAND_ERROR)
+ {
+ return NAND_ERROR;
+ }
+ else if ((data & NAND_READY) == NAND_READY)
+ {
+ return NAND_READY;
+ }
+ else
+ {
+ return NAND_BUSY;
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+#endif /* FMC_Bank3) || defined(FMC_Bank2_3) || defined(FSMC_Bank2_3 */
diff --git a/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nor.c b/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nor.c
new file mode 100644
index 0000000..22366b4
--- /dev/null
+++ b/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nor.c
@@ -0,0 +1,1641 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_nor.c
+ * @author MCD Application Team
+ * @brief NOR HAL module driver.
+ * This file provides a generic firmware to drive NOR memories mounted
+ * as external device.
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver is a generic layered driver which contains a set of APIs used to
+ control NOR flash memories. It uses the FMC/FSMC layer functions to interface
+ with NOR devices. This driver is used as follows:
+
+ (+) NOR flash memory configuration sequence using the function HAL_NOR_Init()
+ with control and timing parameters for both normal and extended mode.
+
+ (+) Read NOR flash memory manufacturer code and device IDs using the function
+ HAL_NOR_Read_ID(). The read information is stored in the NOR_ID_TypeDef
+ structure declared by the function caller.
+
+ (+) Access NOR flash memory by read/write data unit operations using the functions
+ HAL_NOR_Read(), HAL_NOR_Program().
+
+ (+) Perform NOR flash erase block/chip operations using the functions
+ HAL_NOR_Erase_Block() and HAL_NOR_Erase_Chip().
+
+ (+) Read the NOR flash CFI (common flash interface) IDs using the function
+ HAL_NOR_Read_CFI(). The read information is stored in the NOR_CFI_TypeDef
+ structure declared by the function caller.
+
+ (+) You can also control the NOR device by calling the control APIs HAL_NOR_WriteOperation_Enable()/
+ HAL_NOR_WriteOperation_Disable() to respectively enable/disable the NOR write operation
+
+ (+) You can monitor the NOR device HAL state by calling the function
+ HAL_NOR_GetState()
+ [..]
+ (@) This driver is a set of generic APIs which handle standard NOR flash operations.
+ If a NOR flash device contains different operations and/or implementations,
+ it should be implemented separately.
+
+ *** NOR HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in NOR HAL driver.
+
+ (+) NOR_WRITE : NOR memory write data to specified address
+
+ *** Callback registration ***
+ =============================================
+ [..]
+ The compilation define USE_HAL_NOR_REGISTER_CALLBACKS when set to 1
+ allows the user to configure dynamically the driver callbacks.
+
+ Use Functions HAL_NOR_RegisterCallback() to register a user callback,
+ it allows to register following callbacks:
+ (+) MspInitCallback : NOR MspInit.
+ (+) MspDeInitCallback : NOR MspDeInit.
+ This function takes as parameters the HAL peripheral handle, the Callback ID
+ and a pointer to the user callback function.
+
+ Use function HAL_NOR_UnRegisterCallback() to reset a callback to the default
+ weak (overridden) function. It allows to reset following callbacks:
+ (+) MspInitCallback : NOR MspInit.
+ (+) MspDeInitCallback : NOR MspDeInit.
+ This function) takes as parameters the HAL peripheral handle and the Callback ID.
+
+ By default, after the HAL_NOR_Init and if the state is HAL_NOR_STATE_RESET
+ all callbacks are reset to the corresponding legacy weak (overridden) functions.
+ Exception done for MspInit and MspDeInit callbacks that are respectively
+ reset to the legacy weak (overridden) functions in the HAL_NOR_Init
+ and HAL_NOR_DeInit only when these callbacks are null (not registered beforehand).
+ If not, MspInit or MspDeInit are not null, the HAL_NOR_Init and HAL_NOR_DeInit
+ keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
+
+ Callbacks can be registered/unregistered in READY state only.
+ Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
+ in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
+ during the Init/DeInit.
+ In that case first register the MspInit/MspDeInit user callbacks
+ using HAL_NOR_RegisterCallback before calling HAL_NOR_DeInit
+ or HAL_NOR_Init function.
+
+ When The compilation define USE_HAL_NOR_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registering feature is not available
+ and weak (overridden) callbacks are used.
+
+ @endverbatim
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+#if defined(FMC_Bank1) || defined(FSMC_Bank1)
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+
+/** @defgroup NOR NOR
+ * @brief NOR driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup NOR_Private_Defines NOR Private Defines
+ * @{
+ */
+
+/* Constants to define address to set to write a command */
+#define NOR_CMD_ADDRESS_FIRST_BYTE (uint16_t)0x0AAA
+#define NOR_CMD_ADDRESS_FIRST_CFI_BYTE (uint16_t)0x00AA
+#define NOR_CMD_ADDRESS_SECOND_BYTE (uint16_t)0x0555
+#define NOR_CMD_ADDRESS_THIRD_BYTE (uint16_t)0x0AAA
+
+#define NOR_CMD_ADDRESS_FIRST (uint16_t)0x0555
+#define NOR_CMD_ADDRESS_FIRST_CFI (uint16_t)0x0055
+#define NOR_CMD_ADDRESS_SECOND (uint16_t)0x02AA
+#define NOR_CMD_ADDRESS_THIRD (uint16_t)0x0555
+#define NOR_CMD_ADDRESS_FOURTH (uint16_t)0x0555
+#define NOR_CMD_ADDRESS_FIFTH (uint16_t)0x02AA
+#define NOR_CMD_ADDRESS_SIXTH (uint16_t)0x0555
+
+/* Constants to define data to program a command */
+#define NOR_CMD_DATA_READ_RESET (uint16_t)0x00F0
+#define NOR_CMD_DATA_FIRST (uint16_t)0x00AA
+#define NOR_CMD_DATA_SECOND (uint16_t)0x0055
+#define NOR_CMD_DATA_AUTO_SELECT (uint16_t)0x0090
+#define NOR_CMD_DATA_PROGRAM (uint16_t)0x00A0
+#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD (uint16_t)0x0080
+#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH (uint16_t)0x00AA
+#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH (uint16_t)0x0055
+#define NOR_CMD_DATA_CHIP_ERASE (uint16_t)0x0010
+#define NOR_CMD_DATA_CFI (uint16_t)0x0098
+
+#define NOR_CMD_DATA_BUFFER_AND_PROG (uint8_t)0x25
+#define NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM (uint8_t)0x29
+#define NOR_CMD_DATA_BLOCK_ERASE (uint8_t)0x30
+
+#define NOR_CMD_READ_ARRAY (uint16_t)0x00FF
+#define NOR_CMD_WORD_PROGRAM (uint16_t)0x0040
+#define NOR_CMD_BUFFERED_PROGRAM (uint16_t)0x00E8
+#define NOR_CMD_CONFIRM (uint16_t)0x00D0
+#define NOR_CMD_BLOCK_ERASE (uint16_t)0x0020
+#define NOR_CMD_BLOCK_UNLOCK (uint16_t)0x0060
+#define NOR_CMD_READ_STATUS_REG (uint16_t)0x0070
+#define NOR_CMD_CLEAR_STATUS_REG (uint16_t)0x0050
+
+/* Mask on NOR STATUS REGISTER */
+#define NOR_MASK_STATUS_DQ4 (uint16_t)0x0010
+#define NOR_MASK_STATUS_DQ5 (uint16_t)0x0020
+#define NOR_MASK_STATUS_DQ6 (uint16_t)0x0040
+#define NOR_MASK_STATUS_DQ7 (uint16_t)0x0080
+
+/* Address of the primary command set */
+#define NOR_ADDRESS_COMMAND_SET (uint16_t)0x0013
+
+/* Command set code assignment (defined in JEDEC JEP137B version may 2004) */
+#define NOR_INTEL_SHARP_EXT_COMMAND_SET (uint16_t)0x0001 /* Supported in this driver */
+#define NOR_AMD_FUJITSU_COMMAND_SET (uint16_t)0x0002 /* Supported in this driver */
+#define NOR_INTEL_STANDARD_COMMAND_SET (uint16_t)0x0003 /* Not Supported in this driver */
+#define NOR_AMD_FUJITSU_EXT_COMMAND_SET (uint16_t)0x0004 /* Not Supported in this driver */
+#define NOR_WINDBOND_STANDARD_COMMAND_SET (uint16_t)0x0006 /* Not Supported in this driver */
+#define NOR_MITSUBISHI_STANDARD_COMMAND_SET (uint16_t)0x0100 /* Not Supported in this driver */
+#define NOR_MITSUBISHI_EXT_COMMAND_SET (uint16_t)0x0101 /* Not Supported in this driver */
+#define NOR_PAGE_WRITE_COMMAND_SET (uint16_t)0x0102 /* Not Supported in this driver */
+#define NOR_INTEL_PERFORMANCE_COMMAND_SET (uint16_t)0x0200 /* Not Supported in this driver */
+#define NOR_INTEL_DATA_COMMAND_SET (uint16_t)0x0210 /* Not Supported in this driver */
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup NOR_Private_Variables NOR Private Variables
+ * @{
+ */
+
+static uint32_t uwNORMemoryDataWidth = NOR_MEMORY_8B;
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup NOR_Exported_Functions NOR Exported Functions
+ * @{
+ */
+
+/** @defgroup NOR_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### NOR Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to initialize/de-initialize
+ the NOR memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Perform the NOR memory Initialization sequence
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param Timing pointer to NOR control timing structure
+ * @param ExtTiming pointer to NOR extended mode timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FMC_NORSRAM_TimingTypeDef *Timing,
+ FMC_NORSRAM_TimingTypeDef *ExtTiming)
+{
+ uint32_t deviceaddress;
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the NOR handle parameter */
+ if (hnor == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (hnor->State == HAL_NOR_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hnor->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
+ if (hnor->MspInitCallback == NULL)
+ {
+ hnor->MspInitCallback = HAL_NOR_MspInit;
+ }
+
+ /* Init the low level hardware */
+ hnor->MspInitCallback(hnor);
+#else
+ /* Initialize the low level hardware (MSP) */
+ HAL_NOR_MspInit(hnor);
+#endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */
+ }
+
+ /* Initialize NOR control Interface */
+ (void)FMC_NORSRAM_Init(hnor->Instance, &(hnor->Init));
+
+ /* Initialize NOR timing Interface */
+ (void)FMC_NORSRAM_Timing_Init(hnor->Instance, Timing, hnor->Init.NSBank);
+
+ /* Initialize NOR extended mode timing Interface */
+ (void)FMC_NORSRAM_Extended_Timing_Init(hnor->Extended, ExtTiming,
+ hnor->Init.NSBank, hnor->Init.ExtendedMode);
+
+ /* Enable the NORSRAM device */
+ __FMC_NORSRAM_ENABLE(hnor->Instance, hnor->Init.NSBank);
+
+ /* Initialize NOR Memory Data Width*/
+ if (hnor->Init.MemoryDataWidth == FMC_NORSRAM_MEM_BUS_WIDTH_8)
+ {
+ uwNORMemoryDataWidth = NOR_MEMORY_8B;
+ }
+ else
+ {
+ uwNORMemoryDataWidth = NOR_MEMORY_16B;
+ }
+
+ /* Initialize the NOR controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ if (hnor->Init.WriteOperation == FMC_WRITE_OPERATION_DISABLE)
+ {
+ (void)FMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_PROTECTED;
+ }
+ else
+ {
+ /* Get the value of the command set */
+ if (uwNORMemoryDataWidth == NOR_MEMORY_8B)
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI_BYTE),
+ NOR_CMD_DATA_CFI);
+ }
+ else
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI);
+ }
+
+ hnor->CommandSet = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_ADDRESS_COMMAND_SET);
+
+ status = HAL_NOR_ReturnToReadMode(hnor);
+ }
+
+ return status;
+}
+
+/**
+ * @brief Perform NOR memory De-Initialization sequence
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor)
+{
+#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
+ if (hnor->MspDeInitCallback == NULL)
+ {
+ hnor->MspDeInitCallback = HAL_NOR_MspDeInit;
+ }
+
+ /* DeInit the low level hardware */
+ hnor->MspDeInitCallback(hnor);
+#else
+ /* De-Initialize the low level hardware (MSP) */
+ HAL_NOR_MspDeInit(hnor);
+#endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */
+
+ /* Configure the NOR registers with their reset values */
+ (void)FMC_NORSRAM_DeInit(hnor->Instance, hnor->Extended, hnor->Init.NSBank);
+
+ /* Reset the NOR controller state */
+ hnor->State = HAL_NOR_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hnor);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief NOR MSP Init
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval None
+ */
+__weak void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hnor);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_NOR_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief NOR MSP DeInit
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval None
+ */
+__weak void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hnor);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_NOR_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief NOR MSP Wait for Ready/Busy signal
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param Timeout Maximum timeout value
+ * @retval None
+ */
+__weak void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hnor);
+ UNUSED(Timeout);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_NOR_MspWait could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup NOR_Exported_Functions_Group2 Input and Output functions
+ * @brief Input Output and memory control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### NOR Input and Output functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to use and control the NOR memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Read NOR flash IDs
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param pNOR_ID pointer to NOR ID structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID)
+{
+ uint32_t deviceaddress;
+ HAL_NOR_StateTypeDef state;
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the NOR controller state */
+ state = hnor->State;
+ if (state == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (state == HAL_NOR_STATE_PROTECTED)
+ {
+ return HAL_ERROR;
+ }
+ else if (state == HAL_NOR_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Send read ID command */
+ if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
+ {
+ if (uwNORMemoryDataWidth == NOR_MEMORY_8B)
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE),
+ NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE),
+ NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD_BYTE),
+ NOR_CMD_DATA_AUTO_SELECT);
+ }
+ else
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD),
+ NOR_CMD_DATA_AUTO_SELECT);
+ }
+ }
+ else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
+ {
+ NOR_WRITE(deviceaddress, NOR_CMD_DATA_AUTO_SELECT);
+ }
+ else
+ {
+ /* Primary command set not supported by the driver */
+ status = HAL_ERROR;
+ }
+
+ if (status != HAL_ERROR)
+ {
+ /* Read the NOR IDs */
+ pNOR_ID->Manufacturer_Code = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, MC_ADDRESS);
+ pNOR_ID->Device_Code1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth,
+ DEVICE_CODE1_ADDR);
+ pNOR_ID->Device_Code2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth,
+ DEVICE_CODE2_ADDR);
+ pNOR_ID->Device_Code3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth,
+ DEVICE_CODE3_ADDR);
+ }
+
+ /* Check the NOR controller state */
+ hnor->State = state;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Returns the NOR memory to Read mode.
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor)
+{
+ uint32_t deviceaddress;
+ HAL_NOR_StateTypeDef state;
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the NOR controller state */
+ state = hnor->State;
+ if (state == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (state == HAL_NOR_STATE_PROTECTED)
+ {
+ return HAL_ERROR;
+ }
+ else if (state == HAL_NOR_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
+ {
+ NOR_WRITE(deviceaddress, NOR_CMD_DATA_READ_RESET);
+ }
+ else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
+ {
+ NOR_WRITE(deviceaddress, NOR_CMD_READ_ARRAY);
+ }
+ else
+ {
+ /* Primary command set not supported by the driver */
+ status = HAL_ERROR;
+ }
+
+ /* Check the NOR controller state */
+ hnor->State = state;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Read data from NOR memory
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param pAddress pointer to Device address
+ * @param pData pointer to read data
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
+{
+ uint32_t deviceaddress;
+ HAL_NOR_StateTypeDef state;
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the NOR controller state */
+ state = hnor->State;
+ if (state == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (state == HAL_NOR_STATE_PROTECTED)
+ {
+ return HAL_ERROR;
+ }
+ else if (state == HAL_NOR_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Send read data command */
+ if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
+ {
+ if (uwNORMemoryDataWidth == NOR_MEMORY_8B)
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE),
+ NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE),
+ NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD_BYTE),
+ NOR_CMD_DATA_READ_RESET);
+ }
+ else
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD),
+ NOR_CMD_DATA_READ_RESET);
+ }
+ }
+ else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
+ {
+ NOR_WRITE(pAddress, NOR_CMD_READ_ARRAY);
+ }
+ else
+ {
+ /* Primary command set not supported by the driver */
+ status = HAL_ERROR;
+ }
+
+ if (status != HAL_ERROR)
+ {
+ /* Read the data */
+ *pData = (uint16_t)(*(__IO uint32_t *)pAddress);
+ }
+
+ /* Check the NOR controller state */
+ hnor->State = state;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Program data to NOR memory
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param pAddress Device address
+ * @param pData pointer to the data to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
+{
+ uint32_t deviceaddress;
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the NOR controller state */
+ if (hnor->State == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnor->State == HAL_NOR_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Send program data command */
+ if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
+ {
+ if (uwNORMemoryDataWidth == NOR_MEMORY_8B)
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE),
+ NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE),
+ NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD_BYTE),
+ NOR_CMD_DATA_PROGRAM);
+ }
+ else
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_PROGRAM);
+ }
+ }
+ else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
+ {
+ NOR_WRITE(pAddress, NOR_CMD_WORD_PROGRAM);
+ }
+ else
+ {
+ /* Primary command set not supported by the driver */
+ status = HAL_ERROR;
+ }
+
+ if (status != HAL_ERROR)
+ {
+ /* Write the data */
+ NOR_WRITE(pAddress, *pData);
+ }
+
+ /* Check the NOR controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Reads a half-word buffer from the NOR memory.
+ * @param hnor pointer to the NOR handle
+ * @param uwAddress NOR memory internal address to read from.
+ * @param pData pointer to the buffer that receives the data read from the
+ * NOR memory.
+ * @param uwBufferSize number of Half word to read.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData,
+ uint32_t uwBufferSize)
+{
+ uint32_t deviceaddress;
+ uint32_t size = uwBufferSize;
+ uint32_t address = uwAddress;
+ uint16_t *data = pData;
+ HAL_NOR_StateTypeDef state;
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the NOR controller state */
+ state = hnor->State;
+ if (state == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (state == HAL_NOR_STATE_PROTECTED)
+ {
+ return HAL_ERROR;
+ }
+ else if (state == HAL_NOR_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Send read data command */
+ if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
+ {
+ if (uwNORMemoryDataWidth == NOR_MEMORY_8B)
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE),
+ NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE),
+ NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD_BYTE),
+ NOR_CMD_DATA_READ_RESET);
+ }
+ else
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD),
+ NOR_CMD_DATA_READ_RESET);
+ }
+ }
+ else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
+ {
+ NOR_WRITE(deviceaddress, NOR_CMD_READ_ARRAY);
+ }
+ else
+ {
+ /* Primary command set not supported by the driver */
+ status = HAL_ERROR;
+ }
+
+ if (status != HAL_ERROR)
+ {
+ /* Read buffer */
+ while (size > 0U)
+ {
+ *data = *(__IO uint16_t *)address;
+ data++;
+ address += 2U;
+ size--;
+ }
+ }
+
+ /* Check the NOR controller state */
+ hnor->State = state;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Writes a half-word buffer to the NOR memory. This function must be used
+ only with S29GL128P NOR memory.
+ * @param hnor pointer to the NOR handle
+ * @param uwAddress NOR memory internal start write address
+ * @param pData pointer to source data buffer.
+ * @param uwBufferSize Size of the buffer to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData,
+ uint32_t uwBufferSize)
+{
+ uint16_t *p_currentaddress;
+ const uint16_t *p_endaddress;
+ uint16_t *data = pData;
+ uint32_t deviceaddress;
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the NOR controller state */
+ if (hnor->State == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnor->State == HAL_NOR_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Initialize variables */
+ p_currentaddress = (uint16_t *)(deviceaddress + uwAddress);
+ p_endaddress = (uint16_t *)(deviceaddress + uwAddress + (2U * (uwBufferSize - 1U)));
+
+ if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
+ {
+ if (uwNORMemoryDataWidth == NOR_MEMORY_8B)
+ {
+ /* Issue unlock command sequence */
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE),
+ NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE),
+ NOR_CMD_DATA_SECOND);
+ }
+ else
+ {
+ /* Issue unlock command sequence */
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+ }
+ /* Write Buffer Load Command */
+ NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_DATA_BUFFER_AND_PROG);
+ NOR_WRITE((deviceaddress + uwAddress), (uint16_t)(uwBufferSize - 1U));
+ }
+ else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
+ {
+ /* Write Buffer Load Command */
+ NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_BUFFERED_PROGRAM);
+ NOR_WRITE((deviceaddress + uwAddress), (uint16_t)(uwBufferSize - 1U));
+ }
+ else
+ {
+ /* Primary command set not supported by the driver */
+ status = HAL_ERROR;
+ }
+
+ if (status != HAL_ERROR)
+ {
+ /* Load Data into NOR Buffer */
+ while (p_currentaddress <= p_endaddress)
+ {
+ NOR_WRITE(p_currentaddress, *data);
+
+ data++;
+ p_currentaddress ++;
+ }
+
+ if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
+ {
+ NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM);
+ }
+ else /* => hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET */
+ {
+ NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_CONFIRM);
+ }
+ }
+
+ /* Check the NOR controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return status;
+
+}
+
+/**
+ * @brief Erase the specified block of the NOR memory
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param BlockAddress Block to erase address
+ * @param Address Device address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address)
+{
+ uint32_t deviceaddress;
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the NOR controller state */
+ if (hnor->State == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnor->State == HAL_NOR_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Send block erase command sequence */
+ if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
+ {
+ if (uwNORMemoryDataWidth == NOR_MEMORY_8B)
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE),
+ NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE),
+ NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD_BYTE),
+ NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
+ }
+ else
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD),
+ NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH),
+ NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH),
+ NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
+ }
+ NOR_WRITE((uint32_t)(BlockAddress + Address), NOR_CMD_DATA_BLOCK_ERASE);
+ }
+ else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
+ {
+ NOR_WRITE((BlockAddress + Address), NOR_CMD_BLOCK_UNLOCK);
+ NOR_WRITE((BlockAddress + Address), NOR_CMD_CONFIRM);
+ NOR_WRITE((BlockAddress + Address), NOR_CMD_BLOCK_ERASE);
+ NOR_WRITE((BlockAddress + Address), NOR_CMD_CONFIRM);
+ }
+ else
+ {
+ /* Primary command set not supported by the driver */
+ status = HAL_ERROR;
+ }
+
+ /* Check the NOR memory status and update the controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return status;
+
+}
+
+/**
+ * @brief Erase the entire NOR chip.
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param Address Device address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address)
+{
+ uint32_t deviceaddress;
+ HAL_StatusTypeDef status = HAL_OK;
+ UNUSED(Address);
+
+ /* Check the NOR controller state */
+ if (hnor->State == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (hnor->State == HAL_NOR_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Send NOR chip erase command sequence */
+ if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
+ {
+ if (uwNORMemoryDataWidth == NOR_MEMORY_8B)
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE),
+ NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE),
+ NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD_BYTE),
+ NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
+ }
+ else
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD),
+ NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH),
+ NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH),
+ NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SIXTH),
+ NOR_CMD_DATA_CHIP_ERASE);
+ }
+ }
+ else
+ {
+ /* Primary command set not supported by the driver */
+ status = HAL_ERROR;
+ }
+
+ /* Check the NOR memory status and update the controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Read NOR flash CFI IDs
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param pNOR_CFI pointer to NOR CFI IDs structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI)
+{
+ uint32_t deviceaddress;
+ HAL_NOR_StateTypeDef state;
+
+ /* Check the NOR controller state */
+ state = hnor->State;
+ if (state == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+ else if (state == HAL_NOR_STATE_PROTECTED)
+ {
+ return HAL_ERROR;
+ }
+ else if (state == HAL_NOR_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Send read CFI query command */
+ if (uwNORMemoryDataWidth == NOR_MEMORY_8B)
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI_BYTE),
+ NOR_CMD_DATA_CFI);
+ }
+ else
+ {
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI);
+ }
+ /* read the NOR CFI information */
+ pNOR_CFI->CFI_1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI1_ADDRESS);
+ pNOR_CFI->CFI_2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI2_ADDRESS);
+ pNOR_CFI->CFI_3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI3_ADDRESS);
+ pNOR_CFI->CFI_4 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI4_ADDRESS);
+
+ /* Check the NOR controller state */
+ hnor->State = state;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
+/**
+ * @brief Register a User NOR Callback
+ * To be used to override the weak predefined callback
+ * @param hnor : NOR handle
+ * @param CallbackId : ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_NOR_MSP_INIT_CB_ID NOR MspInit callback ID
+ * @arg @ref HAL_NOR_MSP_DEINIT_CB_ID NOR MspDeInit callback ID
+ * @param pCallback : pointer to the Callback function
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_NOR_RegisterCallback(NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId,
+ pNOR_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ HAL_NOR_StateTypeDef state;
+
+ if (pCallback == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ state = hnor->State;
+ if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_RESET) || (state == HAL_NOR_STATE_PROTECTED))
+ {
+ switch (CallbackId)
+ {
+ case HAL_NOR_MSP_INIT_CB_ID :
+ hnor->MspInitCallback = pCallback;
+ break;
+ case HAL_NOR_MSP_DEINIT_CB_ID :
+ hnor->MspDeInitCallback = pCallback;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* update return status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Unregister a User NOR Callback
+ * NOR Callback is redirected to the weak predefined callback
+ * @param hnor : NOR handle
+ * @param CallbackId : ID of the callback to be unregistered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_NOR_MSP_INIT_CB_ID NOR MspInit callback ID
+ * @arg @ref HAL_NOR_MSP_DEINIT_CB_ID NOR MspDeInit callback ID
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_NOR_UnRegisterCallback(NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ HAL_NOR_StateTypeDef state;
+
+ state = hnor->State;
+ if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_RESET) || (state == HAL_NOR_STATE_PROTECTED))
+ {
+ switch (CallbackId)
+ {
+ case HAL_NOR_MSP_INIT_CB_ID :
+ hnor->MspInitCallback = HAL_NOR_MspInit;
+ break;
+ case HAL_NOR_MSP_DEINIT_CB_ID :
+ hnor->MspDeInitCallback = HAL_NOR_MspDeInit;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* update return status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+#endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */
+
+/**
+ * @}
+ */
+
+/** @defgroup NOR_Exported_Functions_Group3 NOR Control functions
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### NOR Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the NOR interface.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables dynamically NOR write operation.
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor)
+{
+ /* Check the NOR controller state */
+ if (hnor->State == HAL_NOR_STATE_PROTECTED)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Enable write operation */
+ (void)FMC_NORSRAM_WriteOperation_Enable(hnor->Instance, hnor->Init.NSBank);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically NOR write operation.
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor)
+{
+ /* Check the NOR controller state */
+ if (hnor->State == HAL_NOR_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Disable write operation */
+ (void)FMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_PROTECTED;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup NOR_Exported_Functions_Group4 NOR State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### NOR State functions #####
+ ==============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the NOR controller
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief return the NOR controller state
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval NOR controller state
+ */
+HAL_NOR_StateTypeDef HAL_NOR_GetState(const NOR_HandleTypeDef *hnor)
+{
+ return hnor->State;
+}
+
+/**
+ * @brief Returns the NOR operation status.
+ * @param hnor pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param Address Device address
+ * @param Timeout NOR programming Timeout
+ * @retval NOR_Status The returned value can be: HAL_NOR_STATUS_SUCCESS, HAL_NOR_STATUS_ERROR
+ * or HAL_NOR_STATUS_TIMEOUT
+ */
+HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout)
+{
+ HAL_NOR_StatusTypeDef status = HAL_NOR_STATUS_ONGOING;
+ uint16_t tmpsr1;
+ uint16_t tmpsr2;
+ uint32_t tickstart;
+
+ /* Poll on NOR memory Ready/Busy signal ------------------------------------*/
+ HAL_NOR_MspWait(hnor, Timeout);
+
+ /* Get the NOR memory operation status -------------------------------------*/
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
+ {
+ while ((status != HAL_NOR_STATUS_SUCCESS) && (status != HAL_NOR_STATUS_TIMEOUT))
+ {
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ status = HAL_NOR_STATUS_TIMEOUT;
+ }
+ }
+
+ /* Read NOR status register (DQ6 and DQ5) */
+ tmpsr1 = *(__IO uint16_t *)Address;
+ tmpsr2 = *(__IO uint16_t *)Address;
+
+ /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS */
+ if ((tmpsr1 & NOR_MASK_STATUS_DQ6) == (tmpsr2 & NOR_MASK_STATUS_DQ6))
+ {
+ return HAL_NOR_STATUS_SUCCESS ;
+ }
+
+ if ((tmpsr1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5)
+ {
+ status = HAL_NOR_STATUS_ONGOING;
+ }
+
+ tmpsr1 = *(__IO uint16_t *)Address;
+ tmpsr2 = *(__IO uint16_t *)Address;
+
+ /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS */
+ if ((tmpsr1 & NOR_MASK_STATUS_DQ6) == (tmpsr2 & NOR_MASK_STATUS_DQ6))
+ {
+ return HAL_NOR_STATUS_SUCCESS;
+ }
+ if ((tmpsr1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5)
+ {
+ return HAL_NOR_STATUS_ERROR;
+ }
+ }
+ }
+ else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
+ {
+ do
+ {
+ NOR_WRITE(Address, NOR_CMD_READ_STATUS_REG);
+ tmpsr2 = *(__IO uint16_t *)(Address);
+
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ return HAL_NOR_STATUS_TIMEOUT;
+ }
+ }
+ } while ((tmpsr2 & NOR_MASK_STATUS_DQ7) == 0U);
+
+ NOR_WRITE(Address, NOR_CMD_READ_STATUS_REG);
+ tmpsr1 = *(__IO uint16_t *)(Address);
+ if ((tmpsr1 & (NOR_MASK_STATUS_DQ5 | NOR_MASK_STATUS_DQ4)) != 0U)
+ {
+ /* Clear the Status Register */
+ NOR_WRITE(Address, NOR_CMD_READ_STATUS_REG);
+ status = HAL_NOR_STATUS_ERROR;
+ }
+ else
+ {
+ status = HAL_NOR_STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ /* Primary command set not supported by the driver */
+ status = HAL_NOR_STATUS_ERROR;
+ }
+
+ /* Return the operation status */
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+#endif /* FMC_Bank1 || FSMC_Bank1 */
diff --git a/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pccard.c b/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pccard.c
new file mode 100644
index 0000000..a568d57
--- /dev/null
+++ b/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pccard.c
@@ -0,0 +1,961 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_pccard.c
+ * @author MCD Application Team
+ * @brief PCCARD HAL module driver.
+ * This file provides a generic firmware to drive PCCARD memories mounted
+ * as external device.
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ @verbatim
+ ===============================================================================
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+ This driver is a generic layered driver which contains a set of APIs used to
+ control PCCARD/compact flash memories. It uses the FMC/FSMC layer functions
+ to interface with PCCARD devices. This driver is used for:
+
+ (+) PCCARD/Compact Flash memory configuration sequence using the function
+ HAL_PCCARD_Init()/HAL_CF_Init() with control and timing parameters for
+ both common and attribute spaces.
+
+ (+) Read PCCARD/Compact Flash memory maker and device IDs using the function
+ HAL_PCCARD_Read_ID()/HAL_CF_Read_ID(). The read information is stored in
+ the CompactFlash_ID structure declared by the function caller.
+
+ (+) Access PCCARD/Compact Flash memory by read/write operations using the functions
+ HAL_PCCARD_Read_Sector()/ HAL_PCCARD_Write_Sector() -
+ HAL_CF_Read_Sector()/HAL_CF_Write_Sector(), to read/write sector.
+
+ (+) Perform PCCARD/Compact Flash Reset chip operation using the function
+ HAL_PCCARD_Reset()/HAL_CF_Reset.
+
+ (+) Perform PCCARD/Compact Flash erase sector operation using the function
+ HAL_PCCARD_Erase_Sector()/HAL_CF_Erase_Sector.
+
+ (+) Read the PCCARD/Compact Flash status operation using the function
+ HAL_PCCARD_ReadStatus()/HAL_CF_ReadStatus().
+
+ (+) You can monitor the PCCARD/Compact Flash device HAL state by calling
+ the function HAL_PCCARD_GetState()/HAL_CF_GetState()
+
+ [..]
+ (@) This driver is a set of generic APIs which handle standard PCCARD/compact flash
+ operations. If a PCCARD/Compact Flash device contains different operations
+ and/or implementations, it should be implemented separately.
+
+ *** Callback registration ***
+ =============================================
+ [..]
+ The compilation define USE_HAL_PCCARD_REGISTER_CALLBACKS when set to 1
+ allows the user to configure dynamically the driver callbacks.
+
+ Use Functions HAL_PCCARD_RegisterCallback() to register a user callback,
+ it allows to register following callbacks:
+ (+) MspInitCallback : PCCARD MspInit.
+ (+) MspDeInitCallback : PCCARD MspDeInit.
+ This function takes as parameters the HAL peripheral handle, the Callback ID
+ and a pointer to the user callback function.
+
+ Use function HAL_PCCARD_UnRegisterCallback() to reset a callback to the default
+ weak (surcharged) function. It allows to reset following callbacks:
+ (+) MspInitCallback : PCCARD MspInit.
+ (+) MspDeInitCallback : PCCARD MspDeInit.
+ This function) takes as parameters the HAL peripheral handle and the Callback ID.
+
+ By default, after the HAL_PCCARD_Init and if the state is HAL_PCCARD_STATE_RESET
+ all callbacks are reset to the corresponding legacy weak (surcharged) functions.
+ Exception done for MspInit and MspDeInit callbacks that are respectively
+ reset to the legacy weak (surcharged) functions in the HAL_PCCARD_Init
+ and HAL_PCCARD_DeInit only when these callbacks are null (not registered beforehand).
+ If not, MspInit or MspDeInit are not null, the HAL_PCCARD_Init and HAL_PCCARD_DeInit
+ keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
+
+ Callbacks can be registered/unregistered in READY state only.
+ Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
+ in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
+ during the Init/DeInit.
+ In that case first register the MspInit/MspDeInit user callbacks
+ using HAL_PCCARD_RegisterCallback before calling HAL_PCCARD_DeInit
+ or HAL_PCCARD_Init function.
+
+ When The compilation define USE_HAL_PCCARD_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registering feature is not available
+ and weak (surcharged) callbacks are used.
+
+ @endverbatim
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+#if defined(FMC_Bank4) || defined(FSMC_Bank4)
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_PCCARD_MODULE_ENABLED
+
+/** @defgroup PCCARD PCCARD
+ * @brief PCCARD HAL module driver
+ * @{
+ */
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup PCCARD_Private_Defines PCCARD Private Defines
+ * @{
+ */
+#define PCCARD_TIMEOUT_READ_ID 0x0000FFFFU
+#define PCCARD_TIMEOUT_READ_WRITE_SECTOR 0x0000FFFFU
+#define PCCARD_TIMEOUT_ERASE_SECTOR 0x00000400U
+#define PCCARD_TIMEOUT_STATUS 0x01000000U
+
+#define PCCARD_STATUS_OK (uint8_t)0x58
+#define PCCARD_STATUS_WRITE_OK (uint8_t)0x50
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function ----------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup PCCARD_Exported_Functions PCCARD Exported Functions
+ * @{
+ */
+
+/** @defgroup PCCARD_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### PCCARD Initialization and de-initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to initialize/de-initialize
+ the PCCARD memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Perform the PCCARD memory Initialization sequence
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @param ComSpaceTiming Common space timing structure
+ * @param AttSpaceTiming Attribute space timing structure
+ * @param IOSpaceTiming IO space timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCCARD_Init(PCCARD_HandleTypeDef *hpccard, FMC_NAND_PCC_TimingTypeDef *ComSpaceTiming,
+ FMC_NAND_PCC_TimingTypeDef *AttSpaceTiming,
+ FMC_NAND_PCC_TimingTypeDef *IOSpaceTiming)
+{
+ /* Check the PCCARD controller state */
+ if (hpccard == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (hpccard->State == HAL_PCCARD_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hpccard->Lock = HAL_UNLOCKED;
+#if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
+ if (hpccard->MspInitCallback == NULL)
+ {
+ hpccard->MspInitCallback = HAL_PCCARD_MspInit;
+ }
+ hpccard->ItCallback = HAL_PCCARD_ITCallback;
+
+ /* Init the low level hardware */
+ hpccard->MspInitCallback(hpccard);
+#else
+ /* Initialize the low level hardware (MSP) */
+ HAL_PCCARD_MspInit(hpccard);
+#endif /* USE_HAL_PCCARD_REGISTER_CALLBACKS */
+ }
+
+ /* Initialize the PCCARD state */
+ hpccard->State = HAL_PCCARD_STATE_BUSY;
+
+ /* Initialize PCCARD control Interface */
+ FMC_PCCARD_Init(hpccard->Instance, &(hpccard->Init));
+
+ /* Init PCCARD common space timing Interface */
+ FMC_PCCARD_CommonSpace_Timing_Init(hpccard->Instance, ComSpaceTiming);
+
+ /* Init PCCARD attribute space timing Interface */
+ FMC_PCCARD_AttributeSpace_Timing_Init(hpccard->Instance, AttSpaceTiming);
+
+ /* Init PCCARD IO space timing Interface */
+ FMC_PCCARD_IOSpace_Timing_Init(hpccard->Instance, IOSpaceTiming);
+
+ /* Enable the PCCARD device */
+ __FMC_PCCARD_ENABLE(hpccard->Instance);
+
+ /* Update the PCCARD state */
+ hpccard->State = HAL_PCCARD_STATE_READY;
+
+ return HAL_OK;
+
+}
+
+/**
+ * @brief Perform the PCCARD memory De-initialization sequence
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCCARD_DeInit(PCCARD_HandleTypeDef *hpccard)
+{
+#if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
+ if (hpccard->MspDeInitCallback == NULL)
+ {
+ hpccard->MspDeInitCallback = HAL_PCCARD_MspDeInit;
+ }
+
+ /* DeInit the low level hardware */
+ hpccard->MspDeInitCallback(hpccard);
+#else
+ /* De-Initialize the low level hardware (MSP) */
+ HAL_PCCARD_MspDeInit(hpccard);
+#endif /* USE_HAL_PCCARD_REGISTER_CALLBACKS */
+
+ /* Configure the PCCARD registers with their reset values */
+ FMC_PCCARD_DeInit(hpccard->Instance);
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hpccard);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief PCCARD MSP Init
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval None
+ */
+__weak void HAL_PCCARD_MspInit(PCCARD_HandleTypeDef *hpccard)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpccard);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_PCCARD_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief PCCARD MSP DeInit
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval None
+ */
+__weak void HAL_PCCARD_MspDeInit(PCCARD_HandleTypeDef *hpccard)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpccard);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_PCCARD_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PCCARD_Exported_Functions_Group2 Input and Output functions
+ * @brief Input Output and memory control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### PCCARD Input and Output functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to use and control the PCCARD memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Read Compact Flash's ID.
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @param CompactFlash_ID Compact flash ID structure.
+ * @param pStatus pointer to compact flash status
+ * @retval HAL status
+ *
+ */
+HAL_StatusTypeDef HAL_PCCARD_Read_ID(PCCARD_HandleTypeDef *hpccard, uint8_t CompactFlash_ID[], uint8_t *pStatus)
+{
+ uint32_t timeout = 0U;
+ uint32_t index = 0U;
+ uint8_t status = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hpccard);
+
+ /* Check the PCCARD controller state */
+ if (hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Initialize timeout value */
+ timeout = PCCARD_TIMEOUT_READ_ID;
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_BUSY;
+
+ /* Initialize the PCCARD status */
+ *pStatus = PCCARD_READY;
+
+ /* Send the Identify Command */
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = (uint16_t)0xECEC;
+
+ /* Read PCCARD IDs and timeout treatment */
+ do
+ {
+ /* Read the PCCARD status */
+ status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+
+ timeout--;
+ } while ((status != PCCARD_STATUS_OK) && timeout);
+
+ if (timeout == 0U)
+ {
+ *pStatus = PCCARD_TIMEOUT_ERROR;
+ }
+ else
+ {
+ /* Read PCCARD ID bytes */
+ for (index = 0U; index < 16U; index++)
+ {
+ CompactFlash_ID[index] = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_DATA);
+ }
+ }
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hpccard);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read sector from PCCARD memory
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @param pBuffer pointer to destination read buffer
+ * @param SectorAddress Sector address to read
+ * @param pStatus pointer to PCCARD status
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCCARD_Read_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress,
+ uint8_t *pStatus)
+{
+ uint32_t timeout = 0U;
+ uint32_t index = 0U;
+ uint8_t status = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hpccard);
+
+ /* Check the PCCARD controller state */
+ if (hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Initialize timeout value */
+ timeout = PCCARD_TIMEOUT_READ_WRITE_SECTOR;
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_BUSY;
+
+ /* Initialize PCCARD status */
+ *pStatus = PCCARD_READY;
+
+ /* Set the parameters to write a sector */
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = (uint16_t)0x0000;
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT) = ((uint16_t)0x0100) | ((uint16_t)SectorAddress);
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = (uint16_t)0xE4A0;
+
+ do
+ {
+ /* wait till the Status = 0x80 */
+ status = *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+ timeout--;
+ } while ((status == 0x80U) && timeout);
+
+ if (timeout == 0U)
+ {
+ *pStatus = PCCARD_TIMEOUT_ERROR;
+ }
+
+ timeout = PCCARD_TIMEOUT_READ_WRITE_SECTOR;
+
+ do
+ {
+ /* wait till the Status = PCCARD_STATUS_OK */
+ status = *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+ timeout--;
+ } while ((status != PCCARD_STATUS_OK) && timeout);
+
+ if (timeout == 0U)
+ {
+ *pStatus = PCCARD_TIMEOUT_ERROR;
+ }
+
+ /* Read bytes */
+ for (; index < PCCARD_SECTOR_SIZE; index++)
+ {
+ *(uint16_t *)pBuffer++ = *(uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR);
+ }
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hpccard);
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Write sector to PCCARD memory
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @param pBuffer pointer to source write buffer
+ * @param SectorAddress Sector address to write
+ * @param pStatus pointer to PCCARD status
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCCARD_Write_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress,
+ uint8_t *pStatus)
+{
+ uint32_t timeout = 0U;
+ uint32_t index = 0U;
+ uint8_t status = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hpccard);
+
+ /* Check the PCCARD controller state */
+ if (hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Initialize timeout value */
+ timeout = PCCARD_TIMEOUT_READ_WRITE_SECTOR;
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_BUSY;
+
+ /* Initialize PCCARD status */
+ *pStatus = PCCARD_READY;
+
+ /* Set the parameters to write a sector */
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = (uint16_t)0x0000;
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT) = ((uint16_t)0x0100) | ((uint16_t)SectorAddress);
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = (uint16_t)0x30A0;
+
+ do
+ {
+ /* Wait till the Status = PCCARD_STATUS_OK */
+ status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+ timeout--;
+ } while ((status != PCCARD_STATUS_OK) && timeout);
+
+ if (timeout == 0U)
+ {
+ *pStatus = PCCARD_TIMEOUT_ERROR;
+ }
+
+ /* Write bytes */
+ for (; index < PCCARD_SECTOR_SIZE; index++)
+ {
+ *(uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR) = *(uint16_t *)pBuffer++;
+ }
+
+ do
+ {
+ /* Wait till the Status = PCCARD_STATUS_WRITE_OK */
+ status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+ timeout--;
+ } while ((status != PCCARD_STATUS_WRITE_OK) && timeout);
+
+ if (timeout == 0U)
+ {
+ *pStatus = PCCARD_TIMEOUT_ERROR;
+ }
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hpccard);
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Erase sector from PCCARD memory
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @param SectorAddress Sector address to erase
+ * @param pStatus pointer to PCCARD status
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCCARD_Erase_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t SectorAddress, uint8_t *pStatus)
+{
+ uint32_t timeout = PCCARD_TIMEOUT_ERASE_SECTOR;
+ uint8_t status = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hpccard);
+
+ /* Check the PCCARD controller state */
+ if (hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_BUSY;
+
+ /* Initialize PCCARD status */
+ *pStatus = PCCARD_READY;
+
+ /* Set the parameters to write a sector */
+ *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_LOW) = 0x00;
+ *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = 0x00;
+ *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_NUMBER) = SectorAddress;
+ *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT) = 0x01;
+ *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CARD_HEAD) = 0xA0;
+ *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = ATA_ERASE_SECTOR_CMD;
+
+ /* wait till the PCCARD is ready */
+ status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+
+ while ((status != PCCARD_STATUS_WRITE_OK) && timeout)
+ {
+ status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+ timeout--;
+ }
+
+ if (timeout == 0U)
+ {
+ *pStatus = PCCARD_TIMEOUT_ERROR;
+ }
+
+ /* Check the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hpccard);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Reset the PCCARD memory
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCCARD_Reset(PCCARD_HandleTypeDef *hpccard)
+{
+ /* Process Locked */
+ __HAL_LOCK(hpccard);
+
+ /* Check the PCCARD controller state */
+ if (hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Provide a SW reset and Read and verify the:
+ - PCCard Configuration Option Register at address 0x98000200 --> 0x80
+ - Card Configuration and Status Register at address 0x98000202 --> 0x00
+ - Pin Replacement Register at address 0x98000204 --> 0x0C
+ - Socket and Copy Register at address 0x98000206 --> 0x00
+ */
+
+ /* Check the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_BUSY;
+
+ *(__IO uint8_t *)(PCCARD_ATTRIBUTE_SPACE_ADDRESS | ATA_CARD_CONFIGURATION) = 0x01;
+
+ /* Check the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hpccard);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles PCCARD device interrupt request.
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval HAL status
+ */
+void HAL_PCCARD_IRQHandler(PCCARD_HandleTypeDef *hpccard)
+{
+ /* Check PCCARD interrupt Rising edge flag */
+ if (__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_RISING_EDGE))
+ {
+ /* PCCARD interrupt callback*/
+#if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
+ hpccard->ItCallback(hpccard);
+#else
+ HAL_PCCARD_ITCallback(hpccard);
+#endif /* USE_HAL_PCCARD_REGISTER_CALLBACKS */
+
+ /* Clear PCCARD interrupt Rising edge pending bit */
+ __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_RISING_EDGE);
+ }
+
+ /* Check PCCARD interrupt Level flag */
+ if (__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_LEVEL))
+ {
+ /* PCCARD interrupt callback*/
+#if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
+ hpccard->ItCallback(hpccard);
+#else
+ HAL_PCCARD_ITCallback(hpccard);
+#endif /* USE_HAL_PCCARD_REGISTER_CALLBACKS */
+
+ /* Clear PCCARD interrupt Level pending bit */
+ __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_LEVEL);
+ }
+
+ /* Check PCCARD interrupt Falling edge flag */
+ if (__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_FALLING_EDGE))
+ {
+ /* PCCARD interrupt callback*/
+#if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
+ hpccard->ItCallback(hpccard);
+#else
+ HAL_PCCARD_ITCallback(hpccard);
+#endif /* USE_HAL_PCCARD_REGISTER_CALLBACKS */
+
+ /* Clear PCCARD interrupt Falling edge pending bit */
+ __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_FALLING_EDGE);
+ }
+
+ /* Check PCCARD interrupt FIFO empty flag */
+ if (__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_FEMPT))
+ {
+ /* PCCARD interrupt callback*/
+#if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
+ hpccard->ItCallback(hpccard);
+#else
+ HAL_PCCARD_ITCallback(hpccard);
+#endif /* USE_HAL_PCCARD_REGISTER_CALLBACKS */
+
+ /* Clear PCCARD interrupt FIFO empty pending bit */
+ __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_FEMPT);
+ }
+}
+
+/**
+ * @brief PCCARD interrupt feature callback
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval None
+ */
+__weak void HAL_PCCARD_ITCallback(PCCARD_HandleTypeDef *hpccard)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpccard);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_PCCARD_ITCallback could be implemented in the user file
+ */
+}
+
+#if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
+/**
+ * @brief Register a User PCCARD Callback
+ * To be used instead of the weak (surcharged) predefined callback
+ * @param hpccard : PCCARD handle
+ * @param CallbackId : ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_PCCARD_MSP_INIT_CB_ID PCCARD MspInit callback ID
+ * @arg @ref HAL_PCCARD_MSP_DEINIT_CB_ID PCCARD MspDeInit callback ID
+ * @arg @ref HAL_PCCARD_IT_CB_ID PCCARD IT callback ID
+ * @param pCallback : pointer to the Callback function
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_PCCARD_RegisterCallback(PCCARD_HandleTypeDef *hpccard, HAL_PCCARD_CallbackIDTypeDef CallbackId,
+ pPCCARD_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process locked */
+ __HAL_LOCK(hpccard);
+
+ if (hpccard->State == HAL_PCCARD_STATE_READY)
+ {
+ switch (CallbackId)
+ {
+ case HAL_PCCARD_MSP_INIT_CB_ID :
+ hpccard->MspInitCallback = pCallback;
+ break;
+ case HAL_PCCARD_MSP_DEINIT_CB_ID :
+ hpccard->MspDeInitCallback = pCallback;
+ break;
+ case HAL_PCCARD_IT_CB_ID :
+ hpccard->ItCallback = pCallback;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (hpccard->State == HAL_PCCARD_STATE_RESET)
+ {
+ switch (CallbackId)
+ {
+ case HAL_PCCARD_MSP_INIT_CB_ID :
+ hpccard->MspInitCallback = pCallback;
+ break;
+ case HAL_PCCARD_MSP_DEINIT_CB_ID :
+ hpccard->MspDeInitCallback = pCallback;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* update return status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hpccard);
+ return status;
+}
+
+/**
+ * @brief Unregister a User PCCARD Callback
+ * PCCARD Callback is redirected to the weak (surcharged) predefined callback
+ * @param hpccard : PCCARD handle
+ * @param CallbackId : ID of the callback to be unregistered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_PCCARD_MSP_INIT_CB_ID PCCARD MspInit callback ID
+ * @arg @ref HAL_PCCARD_MSP_DEINIT_CB_ID PCCARD MspDeInit callback ID
+ * @arg @ref HAL_PCCARD_IT_CB_ID PCCARD IT callback ID
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_PCCARD_UnRegisterCallback(PCCARD_HandleTypeDef *hpccard, HAL_PCCARD_CallbackIDTypeDef CallbackId)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(hpccard);
+
+ if (hpccard->State == HAL_PCCARD_STATE_READY)
+ {
+ switch (CallbackId)
+ {
+ case HAL_PCCARD_MSP_INIT_CB_ID :
+ hpccard->MspInitCallback = HAL_PCCARD_MspInit;
+ break;
+ case HAL_PCCARD_MSP_DEINIT_CB_ID :
+ hpccard->MspDeInitCallback = HAL_PCCARD_MspDeInit;
+ break;
+ case HAL_PCCARD_IT_CB_ID :
+ hpccard->ItCallback = HAL_PCCARD_ITCallback;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (hpccard->State == HAL_PCCARD_STATE_RESET)
+ {
+ switch (CallbackId)
+ {
+ case HAL_PCCARD_MSP_INIT_CB_ID :
+ hpccard->MspInitCallback = HAL_PCCARD_MspInit;
+ break;
+ case HAL_PCCARD_MSP_DEINIT_CB_ID :
+ hpccard->MspDeInitCallback = HAL_PCCARD_MspDeInit;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* update return status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hpccard);
+ return status;
+}
+#endif /* USE_HAL_PCCARD_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/** @defgroup PCCARD_Exported_Functions_Group3 State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### PCCARD State functions #####
+ ==============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the PCCARD controller
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief return the PCCARD controller state
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval HAL state
+ */
+HAL_PCCARD_StateTypeDef HAL_PCCARD_GetState(PCCARD_HandleTypeDef *hpccard)
+{
+ return hpccard->State;
+}
+
+/**
+ * @brief Get the compact flash memory status
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval New status of the PCCARD operation. This parameter can be:
+ * - CompactFlash_TIMEOUT_ERROR: when the previous operation generate
+ * a Timeout error
+ * - CompactFlash_READY: when memory is ready for the next operation
+ */
+HAL_PCCARD_StatusTypeDef HAL_PCCARD_GetStatus(PCCARD_HandleTypeDef *hpccard)
+{
+ uint32_t timeout = PCCARD_TIMEOUT_STATUS;
+ uint32_t status_pccard = 0U;
+
+ /* Check the PCCARD controller state */
+ if (hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_PCCARD_STATUS_ONGOING;
+ }
+
+ status_pccard = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+
+ while ((status_pccard == PCCARD_BUSY) && timeout)
+ {
+ status_pccard = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+ timeout--;
+ }
+
+ if (timeout == 0U)
+ {
+ status_pccard = PCCARD_TIMEOUT_ERROR;
+ }
+
+ /* Return the operation status */
+ return (HAL_PCCARD_StatusTypeDef) status_pccard;
+}
+
+/**
+ * @brief Reads the Compact Flash memory status using the Read status command
+ * @param hpccard pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval The status of the Compact Flash memory. This parameter can be:
+ * - CompactFlash_BUSY: when memory is busy
+ * - CompactFlash_READY: when memory is ready for the next operation
+ * - CompactFlash_ERROR: when the previous operation generates error
+ */
+HAL_PCCARD_StatusTypeDef HAL_PCCARD_ReadStatus(PCCARD_HandleTypeDef *hpccard)
+{
+ uint8_t data = 0U;
+ uint8_t status_pccard = PCCARD_BUSY;
+
+ /* Check the PCCARD controller state */
+ if (hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_PCCARD_STATUS_ONGOING;
+ }
+
+ /* Read status operation */
+ data = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+
+ if ((data & PCCARD_TIMEOUT_ERROR) == PCCARD_TIMEOUT_ERROR)
+ {
+ status_pccard = PCCARD_TIMEOUT_ERROR;
+ }
+ else if ((data & PCCARD_READY) == PCCARD_READY)
+ {
+ status_pccard = PCCARD_READY;
+ }
+
+ return (HAL_PCCARD_StatusTypeDef) status_pccard;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_PCCARD_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+#endif /* FMC_Bank4 || FSMC_Bank4 */
diff --git a/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c b/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c
new file mode 100644
index 0000000..96b06f1
--- /dev/null
+++ b/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c
@@ -0,0 +1,1117 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_sram.c
+ * @author MCD Application Team
+ * @brief SRAM HAL module driver.
+ * This file provides a generic firmware to drive SRAM memories
+ * mounted as external device.
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver is a generic layered driver which contains a set of APIs used to
+ control SRAM memories. It uses the FMC layer functions to interface
+ with SRAM devices.
+ The following sequence should be followed to configure the FMC/FSMC to interface
+ with SRAM/PSRAM memories:
+
+ (#) Declare a SRAM_HandleTypeDef handle structure, for example:
+ SRAM_HandleTypeDef hsram; and:
+
+ (++) Fill the SRAM_HandleTypeDef handle "Init" field with the allowed
+ values of the structure member.
+
+ (++) Fill the SRAM_HandleTypeDef handle "Instance" field with a predefined
+ base register instance for NOR or SRAM device
+
+ (++) Fill the SRAM_HandleTypeDef handle "Extended" field with a predefined
+ base register instance for NOR or SRAM extended mode
+
+ (#) Declare two FMC_NORSRAM_TimingTypeDef structures, for both normal and extended
+ mode timings; for example:
+ FMC_NORSRAM_TimingTypeDef Timing and FMC_NORSRAM_TimingTypeDef ExTiming;
+ and fill its fields with the allowed values of the structure member.
+
+ (#) Initialize the SRAM Controller by calling the function HAL_SRAM_Init(). This function
+ performs the following sequence:
+
+ (##) MSP hardware layer configuration using the function HAL_SRAM_MspInit()
+ (##) Control register configuration using the FMC NORSRAM interface function
+ FMC_NORSRAM_Init()
+ (##) Timing register configuration using the FMC NORSRAM interface function
+ FMC_NORSRAM_Timing_Init()
+ (##) Extended mode Timing register configuration using the FMC NORSRAM interface function
+ FMC_NORSRAM_Extended_Timing_Init()
+ (##) Enable the SRAM device using the macro __FMC_NORSRAM_ENABLE()
+
+ (#) At this stage you can perform read/write accesses from/to the memory connected
+ to the NOR/SRAM Bank. You can perform either polling or DMA transfer using the
+ following APIs:
+ (++) HAL_SRAM_Read()/HAL_SRAM_Write() for polling read/write access
+ (++) HAL_SRAM_Read_DMA()/HAL_SRAM_Write_DMA() for DMA read/write transfer
+
+ (#) You can also control the SRAM device by calling the control APIs HAL_SRAM_WriteOperation_Enable()/
+ HAL_SRAM_WriteOperation_Disable() to respectively enable/disable the SRAM write operation
+
+ (#) You can continuously monitor the SRAM device HAL state by calling the function
+ HAL_SRAM_GetState()
+
+ *** Callback registration ***
+ =============================================
+ [..]
+ The compilation define USE_HAL_SRAM_REGISTER_CALLBACKS when set to 1
+ allows the user to configure dynamically the driver callbacks.
+
+ Use Functions HAL_SRAM_RegisterCallback() to register a user callback,
+ it allows to register following callbacks:
+ (+) MspInitCallback : SRAM MspInit.
+ (+) MspDeInitCallback : SRAM MspDeInit.
+ This function takes as parameters the HAL peripheral handle, the Callback ID
+ and a pointer to the user callback function.
+
+ Use function HAL_SRAM_UnRegisterCallback() to reset a callback to the default
+ weak (overridden) function. It allows to reset following callbacks:
+ (+) MspInitCallback : SRAM MspInit.
+ (+) MspDeInitCallback : SRAM MspDeInit.
+ This function) takes as parameters the HAL peripheral handle and the Callback ID.
+
+ By default, after the HAL_SRAM_Init and if the state is HAL_SRAM_STATE_RESET
+ all callbacks are reset to the corresponding legacy weak (overridden) functions.
+ Exception done for MspInit and MspDeInit callbacks that are respectively
+ reset to the legacy weak (overridden) functions in the HAL_SRAM_Init
+ and HAL_SRAM_DeInit only when these callbacks are null (not registered beforehand).
+ If not, MspInit or MspDeInit are not null, the HAL_SRAM_Init and HAL_SRAM_DeInit
+ keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
+
+ Callbacks can be registered/unregistered in READY state only.
+ Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
+ in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
+ during the Init/DeInit.
+ In that case first register the MspInit/MspDeInit user callbacks
+ using HAL_SRAM_RegisterCallback before calling HAL_SRAM_DeInit
+ or HAL_SRAM_Init function.
+
+ When The compilation define USE_HAL_SRAM_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registering feature is not available
+ and weak (overridden) callbacks are used.
+
+ @endverbatim
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+#if defined(FMC_Bank1) || defined(FSMC_Bank1)
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+
+/** @defgroup SRAM SRAM
+ * @brief SRAM driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup SRAM_Private_Functions SRAM Private Functions
+ * @{
+ */
+static void SRAM_DMACplt(DMA_HandleTypeDef *hdma);
+static void SRAM_DMACpltProt(DMA_HandleTypeDef *hdma);
+static void SRAM_DMAError(DMA_HandleTypeDef *hdma);
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup SRAM_Exported_Functions SRAM Exported Functions
+ * @{
+ */
+
+/** @defgroup SRAM_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions.
+ *
+ @verbatim
+ ==============================================================================
+ ##### SRAM Initialization and de_initialization functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to initialize/de-initialize
+ the SRAM memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Performs the SRAM device initialization sequence
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param Timing Pointer to SRAM control timing structure
+ * @param ExtTiming Pointer to SRAM extended mode timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FMC_NORSRAM_TimingTypeDef *Timing,
+ FMC_NORSRAM_TimingTypeDef *ExtTiming)
+{
+ /* Check the SRAM handle parameter */
+ if (hsram == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (hsram->State == HAL_SRAM_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hsram->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
+ if (hsram->MspInitCallback == NULL)
+ {
+ hsram->MspInitCallback = HAL_SRAM_MspInit;
+ }
+ hsram->DmaXferCpltCallback = HAL_SRAM_DMA_XferCpltCallback;
+ hsram->DmaXferErrorCallback = HAL_SRAM_DMA_XferErrorCallback;
+
+ /* Init the low level hardware */
+ hsram->MspInitCallback(hsram);
+#else
+ /* Initialize the low level hardware (MSP) */
+ HAL_SRAM_MspInit(hsram);
+#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
+ }
+
+ /* Initialize SRAM control Interface */
+ (void)FMC_NORSRAM_Init(hsram->Instance, &(hsram->Init));
+
+ /* Initialize SRAM timing Interface */
+ (void)FMC_NORSRAM_Timing_Init(hsram->Instance, Timing, hsram->Init.NSBank);
+
+ /* Initialize SRAM extended mode timing Interface */
+ (void)FMC_NORSRAM_Extended_Timing_Init(hsram->Extended, ExtTiming, hsram->Init.NSBank,
+ hsram->Init.ExtendedMode);
+
+ /* Enable the NORSRAM device */
+ __FMC_NORSRAM_ENABLE(hsram->Instance, hsram->Init.NSBank);
+
+ /* Initialize the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Performs the SRAM device De-initialization sequence.
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_DeInit(SRAM_HandleTypeDef *hsram)
+{
+#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
+ if (hsram->MspDeInitCallback == NULL)
+ {
+ hsram->MspDeInitCallback = HAL_SRAM_MspDeInit;
+ }
+
+ /* DeInit the low level hardware */
+ hsram->MspDeInitCallback(hsram);
+#else
+ /* De-Initialize the low level hardware (MSP) */
+ HAL_SRAM_MspDeInit(hsram);
+#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
+
+ /* Configure the SRAM registers with their reset values */
+ (void)FMC_NORSRAM_DeInit(hsram->Instance, hsram->Extended, hsram->Init.NSBank);
+
+ /* Reset the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief SRAM MSP Init.
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval None
+ */
+__weak void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsram);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SRAM_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief SRAM MSP DeInit.
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval None
+ */
+__weak void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsram);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SRAM_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DMA transfer complete callback.
+ * @param hdma pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval None
+ */
+__weak void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdma);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SRAM_DMA_XferCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DMA transfer complete error callback.
+ * @param hdma pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval None
+ */
+__weak void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdma);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SRAM_DMA_XferErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SRAM_Exported_Functions_Group2 Input Output and memory control functions
+ * @brief Input Output and memory control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### SRAM Input and Output functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to use and control the SRAM memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Reads 8-bit buffer from SRAM memory.
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress Pointer to read start address
+ * @param pDstBuffer Pointer to destination buffer
+ * @param BufferSize Size of the buffer to read from memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Read_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pDstBuffer,
+ uint32_t BufferSize)
+{
+ uint32_t size;
+ __IO uint8_t *psramaddress = (uint8_t *)pAddress;
+ uint8_t *pdestbuff = pDstBuffer;
+ HAL_SRAM_StateTypeDef state = hsram->State;
+
+ /* Check the SRAM controller state */
+ if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED))
+ {
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Read data from memory */
+ for (size = BufferSize; size != 0U; size--)
+ {
+ *pdestbuff = *psramaddress;
+ pdestbuff++;
+ psramaddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = state;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Writes 8-bit buffer to SRAM memory.
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress Pointer to write start address
+ * @param pSrcBuffer Pointer to source buffer to write
+ * @param BufferSize Size of the buffer to write to memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Write_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pSrcBuffer,
+ uint32_t BufferSize)
+{
+ uint32_t size;
+ __IO uint8_t *psramaddress = (uint8_t *)pAddress;
+ uint8_t *psrcbuff = pSrcBuffer;
+
+ /* Check the SRAM controller state */
+ if (hsram->State == HAL_SRAM_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Write data to memory */
+ for (size = BufferSize; size != 0U; size--)
+ {
+ *psramaddress = *psrcbuff;
+ psrcbuff++;
+ psramaddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Reads 16-bit buffer from SRAM memory.
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress Pointer to read start address
+ * @param pDstBuffer Pointer to destination buffer
+ * @param BufferSize Size of the buffer to read from memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pDstBuffer,
+ uint32_t BufferSize)
+{
+ uint32_t size;
+ __IO uint32_t *psramaddress = pAddress;
+ uint16_t *pdestbuff = pDstBuffer;
+ uint8_t limit;
+ HAL_SRAM_StateTypeDef state = hsram->State;
+
+ /* Check the SRAM controller state */
+ if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED))
+ {
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Check if the size is a 32-bits multiple */
+ limit = (((BufferSize % 2U) != 0U) ? 1U : 0U);
+
+ /* Read data from memory */
+ for (size = BufferSize; size != limit; size -= 2U)
+ {
+ *pdestbuff = (uint16_t)((*psramaddress) & 0x0000FFFFU);
+ pdestbuff++;
+ *pdestbuff = (uint16_t)(((*psramaddress) & 0xFFFF0000U) >> 16U);
+ pdestbuff++;
+ psramaddress++;
+ }
+
+ /* Read last 16-bits if size is not 32-bits multiple */
+ if (limit != 0U)
+ {
+ *pdestbuff = (uint16_t)((*psramaddress) & 0x0000FFFFU);
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = state;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Writes 16-bit buffer to SRAM memory.
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress Pointer to write start address
+ * @param pSrcBuffer Pointer to source buffer to write
+ * @param BufferSize Size of the buffer to write to memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pSrcBuffer,
+ uint32_t BufferSize)
+{
+ uint32_t size;
+ __IO uint32_t *psramaddress = pAddress;
+ uint16_t *psrcbuff = pSrcBuffer;
+ uint8_t limit;
+
+ /* Check the SRAM controller state */
+ if (hsram->State == HAL_SRAM_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Check if the size is a 32-bits multiple */
+ limit = (((BufferSize % 2U) != 0U) ? 1U : 0U);
+
+ /* Write data to memory */
+ for (size = BufferSize; size != limit; size -= 2U)
+ {
+ *psramaddress = (uint32_t)(*psrcbuff);
+ psrcbuff++;
+ *psramaddress |= ((uint32_t)(*psrcbuff) << 16U);
+ psrcbuff++;
+ psramaddress++;
+ }
+
+ /* Write last 16-bits if size is not 32-bits multiple */
+ if (limit != 0U)
+ {
+ *psramaddress = ((uint32_t)(*psrcbuff) & 0x0000FFFFU) | ((*psramaddress) & 0xFFFF0000U);
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Reads 32-bit buffer from SRAM memory.
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress Pointer to read start address
+ * @param pDstBuffer Pointer to destination buffer
+ * @param BufferSize Size of the buffer to read from memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer,
+ uint32_t BufferSize)
+{
+ uint32_t size;
+ __IO uint32_t *psramaddress = pAddress;
+ uint32_t *pdestbuff = pDstBuffer;
+ HAL_SRAM_StateTypeDef state = hsram->State;
+
+ /* Check the SRAM controller state */
+ if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED))
+ {
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Read data from memory */
+ for (size = BufferSize; size != 0U; size--)
+ {
+ *pdestbuff = *psramaddress;
+ pdestbuff++;
+ psramaddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = state;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Writes 32-bit buffer to SRAM memory.
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress Pointer to write start address
+ * @param pSrcBuffer Pointer to source buffer to write
+ * @param BufferSize Size of the buffer to write to memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Write_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer,
+ uint32_t BufferSize)
+{
+ uint32_t size;
+ __IO uint32_t *psramaddress = pAddress;
+ uint32_t *psrcbuff = pSrcBuffer;
+
+ /* Check the SRAM controller state */
+ if (hsram->State == HAL_SRAM_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Write data to memory */
+ for (size = BufferSize; size != 0U; size--)
+ {
+ *psramaddress = *psrcbuff;
+ psrcbuff++;
+ psramaddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Reads a Words data from the SRAM memory using DMA transfer.
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress Pointer to read start address
+ * @param pDstBuffer Pointer to destination buffer
+ * @param BufferSize Size of the buffer to read from memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Read_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer,
+ uint32_t BufferSize)
+{
+ HAL_StatusTypeDef status;
+ HAL_SRAM_StateTypeDef state = hsram->State;
+
+ /* Check the SRAM controller state */
+ if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED))
+ {
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Configure DMA user callbacks */
+ if (state == HAL_SRAM_STATE_READY)
+ {
+ hsram->hdma->XferCpltCallback = SRAM_DMACplt;
+ }
+ else
+ {
+ hsram->hdma->XferCpltCallback = SRAM_DMACpltProt;
+ }
+ hsram->hdma->XferErrorCallback = SRAM_DMAError;
+
+ /* Enable the DMA Stream */
+ status = HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pAddress, (uint32_t)pDstBuffer, (uint32_t)BufferSize);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+ }
+ else
+ {
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Writes a Words data buffer to SRAM memory using DMA transfer.
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress Pointer to write start address
+ * @param pSrcBuffer Pointer to source buffer to write
+ * @param BufferSize Size of the buffer to write to memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Write_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer,
+ uint32_t BufferSize)
+{
+ HAL_StatusTypeDef status;
+
+ /* Check the SRAM controller state */
+ if (hsram->State == HAL_SRAM_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Configure DMA user callbacks */
+ hsram->hdma->XferCpltCallback = SRAM_DMACplt;
+ hsram->hdma->XferErrorCallback = SRAM_DMAError;
+
+ /* Enable the DMA Stream */
+ status = HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pSrcBuffer, (uint32_t)pAddress, (uint32_t)BufferSize);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+ }
+ else
+ {
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
+/**
+ * @brief Register a User SRAM Callback
+ * To be used to override the weak predefined callback
+ * @param hsram : SRAM handle
+ * @param CallbackId : ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_SRAM_MSP_INIT_CB_ID SRAM MspInit callback ID
+ * @arg @ref HAL_SRAM_MSP_DEINIT_CB_ID SRAM MspDeInit callback ID
+ * @param pCallback : pointer to the Callback function
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_SRAM_RegisterCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId,
+ pSRAM_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ HAL_SRAM_StateTypeDef state;
+
+ if (pCallback == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ state = hsram->State;
+ if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_RESET) || (state == HAL_SRAM_STATE_PROTECTED))
+ {
+ switch (CallbackId)
+ {
+ case HAL_SRAM_MSP_INIT_CB_ID :
+ hsram->MspInitCallback = pCallback;
+ break;
+ case HAL_SRAM_MSP_DEINIT_CB_ID :
+ hsram->MspDeInitCallback = pCallback;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* update return status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Unregister a User SRAM Callback
+ * SRAM Callback is redirected to the weak predefined callback
+ * @param hsram : SRAM handle
+ * @param CallbackId : ID of the callback to be unregistered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_SRAM_MSP_INIT_CB_ID SRAM MspInit callback ID
+ * @arg @ref HAL_SRAM_MSP_DEINIT_CB_ID SRAM MspDeInit callback ID
+ * @arg @ref HAL_SRAM_DMA_XFER_CPLT_CB_ID SRAM DMA Xfer Complete callback ID
+ * @arg @ref HAL_SRAM_DMA_XFER_ERR_CB_ID SRAM DMA Xfer Error callback ID
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_SRAM_UnRegisterCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ HAL_SRAM_StateTypeDef state;
+
+ state = hsram->State;
+ if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED))
+ {
+ switch (CallbackId)
+ {
+ case HAL_SRAM_MSP_INIT_CB_ID :
+ hsram->MspInitCallback = HAL_SRAM_MspInit;
+ break;
+ case HAL_SRAM_MSP_DEINIT_CB_ID :
+ hsram->MspDeInitCallback = HAL_SRAM_MspDeInit;
+ break;
+ case HAL_SRAM_DMA_XFER_CPLT_CB_ID :
+ hsram->DmaXferCpltCallback = HAL_SRAM_DMA_XferCpltCallback;
+ break;
+ case HAL_SRAM_DMA_XFER_ERR_CB_ID :
+ hsram->DmaXferErrorCallback = HAL_SRAM_DMA_XferErrorCallback;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (state == HAL_SRAM_STATE_RESET)
+ {
+ switch (CallbackId)
+ {
+ case HAL_SRAM_MSP_INIT_CB_ID :
+ hsram->MspInitCallback = HAL_SRAM_MspInit;
+ break;
+ case HAL_SRAM_MSP_DEINIT_CB_ID :
+ hsram->MspDeInitCallback = HAL_SRAM_MspDeInit;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* update return status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Register a User SRAM Callback for DMA transfers
+ * To be used to override the weak predefined callback
+ * @param hsram : SRAM handle
+ * @param CallbackId : ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_SRAM_DMA_XFER_CPLT_CB_ID SRAM DMA Xfer Complete callback ID
+ * @arg @ref HAL_SRAM_DMA_XFER_ERR_CB_ID SRAM DMA Xfer Error callback ID
+ * @param pCallback : pointer to the Callback function
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_SRAM_RegisterDmaCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId,
+ pSRAM_DmaCallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ HAL_SRAM_StateTypeDef state;
+
+ if (pCallback == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process locked */
+ __HAL_LOCK(hsram);
+
+ state = hsram->State;
+ if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED))
+ {
+ switch (CallbackId)
+ {
+ case HAL_SRAM_DMA_XFER_CPLT_CB_ID :
+ hsram->DmaXferCpltCallback = pCallback;
+ break;
+ case HAL_SRAM_DMA_XFER_ERR_CB_ID :
+ hsram->DmaXferErrorCallback = pCallback;
+ break;
+ default :
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* update return status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hsram);
+ return status;
+}
+#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/** @defgroup SRAM_Exported_Functions_Group3 Control functions
+ * @brief Control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### SRAM Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the SRAM interface.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables dynamically SRAM write operation.
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram)
+{
+ /* Check the SRAM controller state */
+ if (hsram->State == HAL_SRAM_STATE_PROTECTED)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Enable write operation */
+ (void)FMC_NORSRAM_WriteOperation_Enable(hsram->Instance, hsram->Init.NSBank);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically SRAM write operation.
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram)
+{
+ /* Check the SRAM controller state */
+ if (hsram->State == HAL_SRAM_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Disable write operation */
+ (void)FMC_NORSRAM_WriteOperation_Disable(hsram->Instance, hsram->Init.NSBank);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_PROTECTED;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SRAM_Exported_Functions_Group4 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### SRAM State functions #####
+ ==============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the SRAM controller
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the SRAM controller state
+ * @param hsram pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval HAL state
+ */
+HAL_SRAM_StateTypeDef HAL_SRAM_GetState(const SRAM_HandleTypeDef *hsram)
+{
+ return hsram->State;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup SRAM_Private_Functions SRAM Private Functions
+ * @{
+ */
+
+/**
+ * @brief DMA SRAM process complete callback.
+ * @param hdma : DMA handle
+ * @retval None
+ */
+static void SRAM_DMACplt(DMA_HandleTypeDef *hdma)
+{
+ /* Derogation MISRAC2012-Rule-11.5 */
+ SRAM_HandleTypeDef *hsram = (SRAM_HandleTypeDef *)(hdma->Parent);
+
+ /* Disable the DMA channel */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
+ hsram->DmaXferCpltCallback(hdma);
+#else
+ HAL_SRAM_DMA_XferCpltCallback(hdma);
+#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA SRAM process complete callback.
+ * @param hdma : DMA handle
+ * @retval None
+ */
+static void SRAM_DMACpltProt(DMA_HandleTypeDef *hdma)
+{
+ /* Derogation MISRAC2012-Rule-11.5 */
+ SRAM_HandleTypeDef *hsram = (SRAM_HandleTypeDef *)(hdma->Parent);
+
+ /* Disable the DMA channel */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_PROTECTED;
+
+#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
+ hsram->DmaXferCpltCallback(hdma);
+#else
+ HAL_SRAM_DMA_XferCpltCallback(hdma);
+#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA SRAM error callback.
+ * @param hdma : DMA handle
+ * @retval None
+ */
+static void SRAM_DMAError(DMA_HandleTypeDef *hdma)
+{
+ /* Derogation MISRAC2012-Rule-11.5 */
+ SRAM_HandleTypeDef *hsram = (SRAM_HandleTypeDef *)(hdma->Parent);
+
+ /* Disable the DMA channel */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_ERROR;
+
+#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
+ hsram->DmaXferErrorCallback(hdma);
+#else
+ HAL_SRAM_DMA_XferErrorCallback(hdma);
+#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+#endif /* FMC_Bank1 || FSMC_Bank1 */
diff --git a/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c b/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c
new file mode 100644
index 0000000..cf6d201
--- /dev/null
+++ b/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c
@@ -0,0 +1,3807 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_uart.c
+ * @author MCD Application Team
+ * @brief UART HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State and Errors functions
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The UART HAL driver can be used as follows:
+
+ (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart).
+ (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
+ (##) Enable the USARTx interface clock.
+ (##) UART pins configuration:
+ (+++) Enable the clock for the UART GPIOs.
+ (+++) Configure the UART TX/RX pins as alternate function pull-up.
+ (##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
+ and HAL_UART_Receive_IT() APIs):
+ (+++) Configure the USARTx interrupt priority.
+ (+++) Enable the NVIC USART IRQ handle.
+ (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
+ and HAL_UART_Receive_DMA() APIs):
+ (+++) Declare a DMA handle structure for the Tx/Rx stream.
+ (+++) Enable the DMAx interface clock.
+ (+++) Configure the declared DMA handle structure with the required
+ Tx/Rx parameters.
+ (+++) Configure the DMA Tx/Rx stream.
+ (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
+ (+++) Configure the priority and enable the NVIC for the transfer complete
+ interrupt on the DMA Tx/Rx stream.
+ (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
+ (used for last byte sending completion detection in DMA non circular mode)
+
+ (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
+ flow control and Mode(Receiver/Transmitter) in the huart Init structure.
+
+ (#) For the UART asynchronous mode, initialize the UART registers by calling
+ the HAL_UART_Init() API.
+
+ (#) For the UART Half duplex mode, initialize the UART registers by calling
+ the HAL_HalfDuplex_Init() API.
+
+ (#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API.
+
+ (#) For the Multi-Processor mode, initialize the UART registers by calling
+ the HAL_MultiProcessor_Init() API.
+
+ [..]
+ (@) The specific UART interrupts (Transmission complete interrupt,
+ RXNE interrupt and Error Interrupts) will be managed using the macros
+ __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit
+ and receive process.
+
+ [..]
+ (@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the
+ low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customized
+ HAL_UART_MspInit() API.
+
+ ##### Callback registration #####
+ ==================================
+
+ [..]
+ The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1
+ allows the user to configure dynamically the driver callbacks.
+
+ [..]
+ Use Function HAL_UART_RegisterCallback() to register a user callback.
+ Function HAL_UART_RegisterCallback() allows to register following callbacks:
+ (+) TxHalfCpltCallback : Tx Half Complete Callback.
+ (+) TxCpltCallback : Tx Complete Callback.
+ (+) RxHalfCpltCallback : Rx Half Complete Callback.
+ (+) RxCpltCallback : Rx Complete Callback.
+ (+) ErrorCallback : Error Callback.
+ (+) AbortCpltCallback : Abort Complete Callback.
+ (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
+ (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
+ (+) MspInitCallback : UART MspInit.
+ (+) MspDeInitCallback : UART MspDeInit.
+ This function takes as parameters the HAL peripheral handle, the Callback ID
+ and a pointer to the user callback function.
+
+ [..]
+ Use function HAL_UART_UnRegisterCallback() to reset a callback to the default
+ weak (surcharged) function.
+ HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
+ and the Callback ID.
+ This function allows to reset following callbacks:
+ (+) TxHalfCpltCallback : Tx Half Complete Callback.
+ (+) TxCpltCallback : Tx Complete Callback.
+ (+) RxHalfCpltCallback : Rx Half Complete Callback.
+ (+) RxCpltCallback : Rx Complete Callback.
+ (+) ErrorCallback : Error Callback.
+ (+) AbortCpltCallback : Abort Complete Callback.
+ (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
+ (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
+ (+) MspInitCallback : UART MspInit.
+ (+) MspDeInitCallback : UART MspDeInit.
+
+ [..]
+ For specific callback RxEventCallback, use dedicated registration/reset functions:
+ respectively HAL_UART_RegisterRxEventCallback() , HAL_UART_UnRegisterRxEventCallback().
+
+ [..]
+ By default, after the HAL_UART_Init() and when the state is HAL_UART_STATE_RESET
+ all callbacks are set to the corresponding weak (surcharged) functions:
+ examples HAL_UART_TxCpltCallback(), HAL_UART_RxHalfCpltCallback().
+ Exception done for MspInit and MspDeInit functions that are respectively
+ reset to the legacy weak (surcharged) functions in the HAL_UART_Init()
+ and HAL_UART_DeInit() only when these callbacks are null (not registered beforehand).
+ If not, MspInit or MspDeInit are not null, the HAL_UART_Init() and HAL_UART_DeInit()
+ keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
+
+ [..]
+ Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only.
+ Exception done MspInit/MspDeInit that can be registered/unregistered
+ in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user)
+ MspInit/DeInit callbacks can be used during the Init/DeInit.
+ In that case first register the MspInit/MspDeInit user callbacks
+ using HAL_UART_RegisterCallback() before calling HAL_UART_DeInit()
+ or HAL_UART_Init() function.
+
+ [..]
+ When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registration feature is not available
+ and weak (surcharged) callbacks are used.
+
+ [..]
+ Three operation modes are available within this driver :
+
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Send an amount of data in blocking mode using HAL_UART_Transmit()
+ (+) Receive an amount of data in blocking mode using HAL_UART_Receive()
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT()
+ (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT()
+ (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxCpltCallback
+ (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_UART_ErrorCallback
+
+ *** DMA mode IO operation ***
+ ==============================
+ [..]
+ (+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA()
+ (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback
+ (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA()
+ (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback
+ (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxCpltCallback
+ (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_UART_ErrorCallback
+ (+) Pause the DMA Transfer using HAL_UART_DMAPause()
+ (+) Resume the DMA Transfer using HAL_UART_DMAResume()
+ (+) Stop the DMA Transfer using HAL_UART_DMAStop()
+
+
+ [..] This subsection also provides a set of additional functions providing enhanced reception
+ services to user. (For example, these functions allow application to handle use cases
+ where number of data to be received is unknown).
+
+ (#) Compared to standard reception services which only consider number of received
+ data elements as reception completion criteria, these functions also consider additional events
+ as triggers for updating reception status to caller :
+ (+) Detection of inactivity period (RX line has not been active for a given period).
+ (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state)
+ for 1 frame time, after last received byte.
+
+ (#) There are two mode of transfer:
+ (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received,
+ or till IDLE event occurs. Reception is handled only during function execution.
+ When function exits, no data reception could occur. HAL status and number of actually received data elements,
+ are returned by function after finishing transfer.
+ (+) Non-Blocking mode: The reception is performed using Interrupts or DMA.
+ These API's return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode.
+ The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process
+ The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected.
+
+ (#) Blocking mode API:
+ (+) HAL_UARTEx_ReceiveToIdle()
+
+ (#) Non-Blocking mode API with Interrupt:
+ (+) HAL_UARTEx_ReceiveToIdle_IT()
+
+ (#) Non-Blocking mode API with DMA:
+ (+) HAL_UARTEx_ReceiveToIdle_DMA()
+
+
+ *** UART HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in UART HAL driver.
+
+ (+) __HAL_UART_ENABLE: Enable the UART peripheral
+ (+) __HAL_UART_DISABLE: Disable the UART peripheral
+ (+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not
+ (+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag
+ (+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt
+ (+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt
+ (+) __HAL_UART_GET_IT_SOURCE: Check whether the specified UART interrupt has occurred or not
+
+ [..]
+ (@) You can refer to the UART HAL driver header file for more useful macros
+
+ @endverbatim
+ [..]
+ (@) Additional remark: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ the possible UART frame formats are as listed in the following table:
+ +-------------------------------------------------------------+
+ | M bit | PCE bit | UART frame |
+ |---------------------|---------------------------------------|
+ | 0 | 0 | | SB | 8 bit data | STB | |
+ |---------|-----------|---------------------------------------|
+ | 0 | 1 | | SB | 7 bit data | PB | STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 0 | | SB | 9 bit data | STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 1 | | SB | 8 bit data | PB | STB | |
+ +-------------------------------------------------------------+
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup UART UART
+ * @brief HAL UART module driver
+ * @{
+ */
+#ifdef HAL_UART_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup UART_Private_Constants
+ * @{
+ */
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup UART_Private_Functions UART Private Functions
+ * @{
+ */
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
+static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
+static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMAError(DMA_HandleTypeDef *hdma);
+static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
+static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
+ uint32_t Tickstart, uint32_t Timeout);
+static void UART_SetConfig(UART_HandleTypeDef *huart);
+
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+/** @defgroup UART_Exported_Functions UART Exported Functions
+ * @{
+ */
+
+/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and Configuration functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
+ in asynchronous mode.
+ (+) For the asynchronous mode only these parameters can be configured:
+ (++) Baud Rate
+ (++) Word Length
+ (++) Stop Bit
+ (++) Parity: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ please refer to Reference manual for possible UART frame formats.
+ (++) Hardware flow control
+ (++) Receiver/transmitter modes
+ (++) Over Sampling Method
+ [..]
+ The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init() and HAL_MultiProcessor_Init() APIs
+ follow respectively the UART asynchronous, UART Half duplex, LIN and Multi-Processor configuration
+ procedures (details for the procedures are available in reference manual
+ (RM0430 for STM32F4X3xx MCUs and RM0402 for STM32F412xx MCUs
+ RM0383 for STM32F411xC/E MCUs and RM0401 for STM32F410xx MCUs
+ RM0090 for STM32F4X5xx/STM32F4X7xx/STM32F429xx/STM32F439xx MCUs
+ RM0390 for STM32F446xx MCUs and RM0386 for STM32F469xx/STM32F479xx MCUs)).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the UART mode according to the specified parameters in
+ * the UART_InitTypeDef and create the associated handle.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
+ {
+ /* The hardware flow control is available only for USART1, USART2, USART3 and USART6.
+ Except for STM32F446xx devices, that is available for USART1, USART2, USART3, USART6, UART4 and UART5.
+ */
+ assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
+ assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
+ }
+ else
+ {
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+ }
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+
+ if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ UART_InitCallbacksToDefault(huart);
+
+ if (huart->MspInitCallback == NULL)
+ {
+ huart->MspInitCallback = HAL_UART_MspInit;
+ }
+
+ /* Init the low level hardware */
+ huart->MspInitCallback(huart);
+#else
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In asynchronous mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the half-duplex mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+
+ if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ UART_InitCallbacksToDefault(huart);
+
+ if (huart->MspInitCallback == NULL)
+ {
+ huart->MspInitCallback = HAL_UART_MspInit;
+ }
+
+ /* Init the low level hardware */
+ huart->MspInitCallback(huart);
+#else
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In half-duplex mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
+
+ /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
+ SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state*/
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the LIN mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param BreakDetectLength Specifies the LIN break detection length.
+ * This parameter can be one of the following values:
+ * @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection
+ * @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the LIN UART instance */
+ assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
+
+ /* Check the Break detection length parameter */
+ assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
+ assert_param(IS_UART_LIN_WORD_LENGTH(huart->Init.WordLength));
+ assert_param(IS_UART_LIN_OVERSAMPLING(huart->Init.OverSampling));
+
+ if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ UART_InitCallbacksToDefault(huart);
+
+ if (huart->MspInitCallback == NULL)
+ {
+ huart->MspInitCallback = HAL_UART_MspInit;
+ }
+
+ /* Init the low level hardware */
+ huart->MspInitCallback(huart);
+#else
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In LIN mode, the following bits must be kept cleared:
+ - CLKEN bits in the USART_CR2 register,
+ - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
+
+ /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
+ SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
+
+ /* Set the USART LIN Break detection length. */
+ CLEAR_BIT(huart->Instance->CR2, USART_CR2_LBDL);
+ SET_BIT(huart->Instance->CR2, BreakDetectLength);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state*/
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the Multi-Processor mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param Address USART address
+ * @param WakeUpMethod specifies the USART wake-up method.
+ * This parameter can be one of the following values:
+ * @arg UART_WAKEUPMETHOD_IDLELINE: Wake-up by an idle line detection
+ * @arg UART_WAKEUPMETHOD_ADDRESSMARK: Wake-up by an address mark
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Check the Address & wake up method parameters */
+ assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
+ assert_param(IS_UART_ADDRESS(Address));
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+
+ if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ UART_InitCallbacksToDefault(huart);
+
+ if (huart->MspInitCallback == NULL)
+ {
+ huart->MspInitCallback = HAL_UART_MspInit;
+ }
+
+ /* Init the low level hardware */
+ huart->MspInitCallback(huart);
+#else
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In Multi-Processor mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN, HDSEL and IREN bits in the USART_CR3 register */
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+ /* Set the USART address node */
+ CLEAR_BIT(huart->Instance->CR2, USART_CR2_ADD);
+ SET_BIT(huart->Instance->CR2, Address);
+
+ /* Set the wake up method by setting the WAKE bit in the CR1 register */
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_WAKE);
+ SET_BIT(huart->Instance->CR1, WakeUpMethod);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the UART peripheral.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the Peripheral */
+ __HAL_UART_DISABLE(huart);
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ if (huart->MspDeInitCallback == NULL)
+ {
+ huart->MspDeInitCallback = HAL_UART_MspDeInit;
+ }
+ /* DeInit the low level hardware */
+ huart->MspDeInitCallback(huart);
+#else
+ /* DeInit the low level hardware */
+ HAL_UART_MspDeInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_RESET;
+ huart->RxState = HAL_UART_STATE_RESET;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ /* Process Unlock */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief UART MSP Init.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART MSP DeInit.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_MspDeInit could be implemented in the user file
+ */
+}
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+/**
+ * @brief Register a User UART Callback
+ * To be used instead of the weak predefined callback
+ * @note The HAL_UART_RegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(),
+ * HAL_MultiProcessor_Init() to register callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID
+ * @param huart uart handle
+ * @param CallbackID ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
+ * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
+ * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
+ * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
+ * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
+ * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
+ * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
+ * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
+ * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
+ * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
+ * @param pCallback pointer to the Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
+ pUART_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ return HAL_ERROR;
+ }
+
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ switch (CallbackID)
+ {
+ case HAL_UART_TX_HALFCOMPLETE_CB_ID :
+ huart->TxHalfCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_TX_COMPLETE_CB_ID :
+ huart->TxCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_RX_HALFCOMPLETE_CB_ID :
+ huart->RxHalfCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_RX_COMPLETE_CB_ID :
+ huart->RxCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_ERROR_CB_ID :
+ huart->ErrorCallback = pCallback;
+ break;
+
+ case HAL_UART_ABORT_COMPLETE_CB_ID :
+ huart->AbortCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
+ huart->AbortTransmitCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
+ huart->AbortReceiveCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_MSPINIT_CB_ID :
+ huart->MspInitCallback = pCallback;
+ break;
+
+ case HAL_UART_MSPDEINIT_CB_ID :
+ huart->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ switch (CallbackID)
+ {
+ case HAL_UART_MSPINIT_CB_ID :
+ huart->MspInitCallback = pCallback;
+ break;
+
+ case HAL_UART_MSPDEINIT_CB_ID :
+ huart->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Unregister an UART Callback
+ * UART callaback is redirected to the weak predefined callback
+ * @note The HAL_UART_UnRegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(),
+ * HAL_LIN_Init(), HAL_MultiProcessor_Init() to un-register callbacks for HAL_UART_MSPINIT_CB_ID
+ * and HAL_UART_MSPDEINIT_CB_ID
+ * @param huart uart handle
+ * @param CallbackID ID of the callback to be unregistered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
+ * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
+ * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
+ * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
+ * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
+ * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
+ * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
+ * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
+ * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
+ * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (HAL_UART_STATE_READY == huart->gState)
+ {
+ switch (CallbackID)
+ {
+ case HAL_UART_TX_HALFCOMPLETE_CB_ID :
+ huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
+ break;
+
+ case HAL_UART_TX_COMPLETE_CB_ID :
+ huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
+ break;
+
+ case HAL_UART_RX_HALFCOMPLETE_CB_ID :
+ huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
+ break;
+
+ case HAL_UART_RX_COMPLETE_CB_ID :
+ huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
+ break;
+
+ case HAL_UART_ERROR_CB_ID :
+ huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
+ break;
+
+ case HAL_UART_ABORT_COMPLETE_CB_ID :
+ huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
+ break;
+
+ case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
+ huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
+ break;
+
+ case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
+ huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
+ break;
+
+ case HAL_UART_MSPINIT_CB_ID :
+ huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */
+ break;
+
+ case HAL_UART_MSPDEINIT_CB_ID :
+ huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */
+ break;
+
+ default :
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (HAL_UART_STATE_RESET == huart->gState)
+ {
+ switch (CallbackID)
+ {
+ case HAL_UART_MSPINIT_CB_ID :
+ huart->MspInitCallback = HAL_UART_MspInit;
+ break;
+
+ case HAL_UART_MSPDEINIT_CB_ID :
+ huart->MspDeInitCallback = HAL_UART_MspDeInit;
+ break;
+
+ default :
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Register a User UART Rx Event Callback
+ * To be used instead of the weak predefined callback
+ * @param huart Uart handle
+ * @param pCallback Pointer to the Rx Event Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ return HAL_ERROR;
+ }
+
+ /* Process locked */
+ __HAL_LOCK(huart);
+
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ huart->RxEventCallback = pCallback;
+ }
+ else
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(huart);
+
+ return status;
+}
+
+/**
+ * @brief UnRegister the UART Rx Event Callback
+ * UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback
+ * @param huart Uart handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(huart);
+
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback */
+ }
+ else
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(huart);
+ return status;
+}
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group2 IO operation functions
+ * @brief UART Transmit and Receive functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ This subsection provides a set of functions allowing to manage the UART asynchronous
+ and Half duplex data transfers.
+
+ (#) There are two modes of transfer:
+ (+) Blocking mode: The communication is performed in polling mode.
+ The HAL status of all data processing is returned by the same function
+ after finishing transfer.
+ (+) Non-Blocking mode: The communication is performed using Interrupts
+ or DMA, these API's return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+ The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
+ will be executed respectively at the end of the transmit or receive process
+ The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected.
+
+ (#) Blocking mode API's are :
+ (+) HAL_UART_Transmit()
+ (+) HAL_UART_Receive()
+
+ (#) Non-Blocking mode API's with Interrupt are :
+ (+) HAL_UART_Transmit_IT()
+ (+) HAL_UART_Receive_IT()
+ (+) HAL_UART_IRQHandler()
+
+ (#) Non-Blocking mode API's with DMA are :
+ (+) HAL_UART_Transmit_DMA()
+ (+) HAL_UART_Receive_DMA()
+ (+) HAL_UART_DMAPause()
+ (+) HAL_UART_DMAResume()
+ (+) HAL_UART_DMAStop()
+
+ (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
+ (+) HAL_UART_TxHalfCpltCallback()
+ (+) HAL_UART_TxCpltCallback()
+ (+) HAL_UART_RxHalfCpltCallback()
+ (+) HAL_UART_RxCpltCallback()
+ (+) HAL_UART_ErrorCallback()
+
+ (#) Non-Blocking mode transfers could be aborted using Abort API's :
+ (+) HAL_UART_Abort()
+ (+) HAL_UART_AbortTransmit()
+ (+) HAL_UART_AbortReceive()
+ (+) HAL_UART_Abort_IT()
+ (+) HAL_UART_AbortTransmit_IT()
+ (+) HAL_UART_AbortReceive_IT()
+
+ (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
+ (+) HAL_UART_AbortCpltCallback()
+ (+) HAL_UART_AbortTransmitCpltCallback()
+ (+) HAL_UART_AbortReceiveCpltCallback()
+
+ (#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced reception services:
+ (+) HAL_UARTEx_RxEventCallback()
+
+ (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
+ Errors are handled as follows :
+ (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
+ to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
+ Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
+ and HAL_UART_ErrorCallback() user callback is executed. Transfer is kept ongoing on UART side.
+ If user wants to abort it, Abort services should be called by user.
+ (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
+ This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
+ Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
+
+ -@- In the Half duplex communication, it is forbidden to run the transmit
+ and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sends an amount of data in blocking mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the sent data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 provided through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be sent
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ const uint8_t *pdata8bits;
+ const uint16_t *pdata16bits;
+ uint32_t tickstart = 0U;
+
+ /* Check that a Tx process is not already ongoing */
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_BUSY_TX;
+
+ /* Init tickstart for timeout management */
+ tickstart = HAL_GetTick();
+
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+
+ /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ pdata8bits = NULL;
+ pdata16bits = (const uint16_t *) pData;
+ }
+ else
+ {
+ pdata8bits = pData;
+ pdata16bits = NULL;
+ }
+
+ while (huart->TxXferCount > 0U)
+ {
+ if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ huart->gState = HAL_UART_STATE_READY;
+
+ return HAL_TIMEOUT;
+ }
+ if (pdata8bits == NULL)
+ {
+ huart->Instance->DR = (uint16_t)(*pdata16bits & 0x01FFU);
+ pdata16bits++;
+ }
+ else
+ {
+ huart->Instance->DR = (uint8_t)(*pdata8bits & 0xFFU);
+ pdata8bits++;
+ }
+ huart->TxXferCount--;
+ }
+
+ if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ huart->gState = HAL_UART_STATE_READY;
+
+ return HAL_TIMEOUT;
+ }
+
+ /* At end of Tx process, restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in blocking mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the received data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 available through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint8_t *pdata8bits;
+ uint16_t *pdata16bits;
+ uint32_t tickstart = 0U;
+
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Init tickstart for timeout management */
+ tickstart = HAL_GetTick();
+
+ huart->RxXferSize = Size;
+ huart->RxXferCount = Size;
+
+ /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ pdata8bits = NULL;
+ pdata16bits = (uint16_t *) pData;
+ }
+ else
+ {
+ pdata8bits = pData;
+ pdata16bits = NULL;
+ }
+
+ /* Check the remain data to be received */
+ while (huart->RxXferCount > 0U)
+ {
+ if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_TIMEOUT;
+ }
+ if (pdata8bits == NULL)
+ {
+ *pdata16bits = (uint16_t)(huart->Instance->DR & 0x01FF);
+ pdata16bits++;
+ }
+ else
+ {
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
+ }
+ pdata8bits++;
+ }
+ huart->RxXferCount--;
+ }
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the sent data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 provided through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Tx process is not already ongoing */
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ huart->pTxBuffPtr = pData;
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_BUSY_TX;
+
+ /* Enable the UART Transmit data register empty Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the received data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 available through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Set Reception type to Standard reception */
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ return (UART_Start_Receive_IT(huart, pData, Size));
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sends an amount of data in DMA mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the sent data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 provided through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
+{
+ const uint32_t *tmp;
+
+ /* Check that a Tx process is not already ongoing */
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ huart->pTxBuffPtr = pData;
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_BUSY_TX;
+
+ /* Set the UART DMA transfer complete callback */
+ huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
+
+ /* Set the UART DMA Half transfer complete callback */
+ huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
+
+ /* Set the DMA error callback */
+ huart->hdmatx->XferErrorCallback = UART_DMAError;
+
+ /* Set the DMA abort callback */
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the UART transmit DMA stream */
+ tmp = (const uint32_t *)&pData;
+ if (HAL_DMA_Start_IT(huart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size) != HAL_OK)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ /* Restore huart->gState to ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ return HAL_ERROR;
+ }
+ /* Clear the TC flag in the SR register by writing 0 to it */
+ __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
+
+ /* Enable the DMA transfer for transmit request by setting the DMAT bit
+ in the UART CR3 register */
+ ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in DMA mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the received data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 available through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @note When the UART parity is enabled (PCE = 1) the received data contains the parity bit.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Set Reception type to Standard reception */
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ return (UART_Start_Receive_DMA(huart, pData, Size));
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Pauses the DMA Transfer.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
+{
+ uint32_t dmarequest = 0x00U;
+
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
+ if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
+ {
+ /* Disable the UART DMA Tx request */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+ }
+
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
+ {
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the UART DMA Rx request */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Resumes the DMA Transfer.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
+{
+
+ if (huart->gState == HAL_UART_STATE_BUSY_TX)
+ {
+ /* Enable the UART DMA Tx request */
+ ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+ }
+
+ if (huart->RxState == HAL_UART_STATE_BUSY_RX)
+ {
+ /* Clear the Overrun flag before resuming the Rx transfer*/
+ __HAL_UART_CLEAR_OREFLAG(huart);
+
+ /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
+ if (huart->Init.Parity != UART_PARITY_NONE)
+ {
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ }
+ ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the UART DMA Rx request */
+ ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the DMA Transfer.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
+{
+ uint32_t dmarequest = 0x00U;
+ /* The Lock is not implemented on this API to allow the user application
+ to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():
+ when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
+ and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
+ */
+
+ /* Stop UART DMA Tx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
+ if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx stream */
+ if (huart->hdmatx != NULL)
+ {
+ HAL_DMA_Abort(huart->hdmatx);
+ }
+ UART_EndTxTransfer(huart);
+ }
+
+ /* Stop UART DMA Rx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx stream */
+ if (huart->hdmarx != NULL)
+ {
+ HAL_DMA_Abort(huart->hdmarx);
+ }
+ UART_EndRxTransfer(huart);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Receive an amount of data in blocking mode till either the expected number of data is received or an IDLE event occurs.
+ * @note HAL_OK is returned if reception is completed (expected number of data has been received)
+ * or if reception is stopped after IDLE event (less than the expected number of data has been received)
+ * In this case, RxLen output parameter indicates number of data available in reception buffer.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
+ * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
+ * of uint16_t available through pData.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
+ * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
+ * @param RxLen Number of data elements finally received (could be lower than Size, in case reception ends on IDLE event)
+ * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
+ uint32_t Timeout)
+{
+ uint8_t *pdata8bits;
+ uint16_t *pdata16bits;
+ uint32_t tickstart;
+
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+ huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ /* Init tickstart for timeout management */
+ tickstart = HAL_GetTick();
+
+ huart->RxXferSize = Size;
+ huart->RxXferCount = Size;
+
+ /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ pdata8bits = NULL;
+ pdata16bits = (uint16_t *) pData;
+ }
+ else
+ {
+ pdata8bits = pData;
+ pdata16bits = NULL;
+ }
+
+ /* Initialize output number of received elements */
+ *RxLen = 0U;
+
+ /* as long as data have to be received */
+ while (huart->RxXferCount > 0U)
+ {
+ /* Check if IDLE flag is set */
+ if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
+ {
+ /* Clear IDLE flag in ISR */
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+
+ /* If Set, but no data ever received, clear flag without exiting loop */
+ /* If Set, and data has already been received, this means Idle Event is valid : End reception */
+ if (*RxLen > 0U)
+ {
+ huart->RxEventType = HAL_UART_RXEVENT_IDLE;
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+ }
+ }
+
+ /* Check if RXNE flag is set */
+ if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE))
+ {
+ if (pdata8bits == NULL)
+ {
+ *pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
+ pdata16bits++;
+ }
+ else
+ {
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
+ }
+
+ pdata8bits++;
+ }
+ /* Increment number of received elements */
+ *RxLen += 1U;
+ huart->RxXferCount--;
+ }
+
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Set number of received elements in output parameter : RxLen */
+ *RxLen = huart->RxXferSize - huart->RxXferCount;
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in interrupt mode till either the expected number of data is received or an IDLE event occurs.
+ * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
+ * to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating
+ * number of received data elements.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
+ * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
+ * of uint16_t available through pData.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
+ * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef status;
+
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Set Reception type to reception till IDLE Event*/
+ huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ status = UART_Start_Receive_IT(huart, pData, Size);
+
+ /* Check Rx process has been successfully started */
+ if (status == HAL_OK)
+ {
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+ }
+ else
+ {
+ /* In case of errors already pending when reception is started,
+ Interrupts may have already been raised and lead to reception abortion.
+ (Overrun error for instance).
+ In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
+ status = HAL_ERROR;
+ }
+ }
+
+ return status;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in DMA mode till either the expected number of data is received or an IDLE event occurs.
+ * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
+ * to DMA services, transferring automatically received data elements in user reception buffer and
+ * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
+ * reception phase as ended. In all cases, callback execution will indicate number of received data elements.
+ * @note When the UART parity is enabled (PCE = 1), the received data contain
+ * the parity bit (MSB position).
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
+ * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
+ * of uint16_t available through pData.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
+ * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef status;
+
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Set Reception type to reception till IDLE Event*/
+ huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ status = UART_Start_Receive_DMA(huart, pData, Size);
+
+ /* Check Rx process has been successfully started */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+ }
+ else
+ {
+ /* In case of errors already pending when reception is started,
+ Interrupts may have already been raised and lead to reception abortion.
+ (Overrun error for instance).
+ In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
+ status = HAL_ERROR;
+ }
+
+ return status;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Provide Rx Event type that has lead to RxEvent callback execution.
+ * @note When HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, progress
+ * of reception process is provided to application through calls of Rx Event callback (either default one
+ * HAL_UARTEx_RxEventCallback() or user registered one). As several types of events could occur (IDLE event,
+ * Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead
+ * to Rx Event callback execution.
+ * @note This function is expected to be called within the user implementation of Rx Event Callback,
+ * in order to provide the accurate value :
+ * In Interrupt Mode :
+ * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
+ * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
+ * received data is lower than expected one)
+ * In DMA Mode :
+ * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
+ * - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received
+ * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
+ * received data is lower than expected one).
+ * In DMA mode, RxEvent callback could be called several times;
+ * When DMA is configured in Normal Mode, HT event does not stop Reception process;
+ * When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process;
+ * @param huart UART handle.
+ * @retval Rx Event Type (returned value will be a value of @ref UART_RxEvent_Type_Values)
+ */
+HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(UART_HandleTypeDef *huart)
+{
+ /* Return Rx Event type value, as stored in UART handle */
+ return(huart->RxEventType);
+}
+
+/**
+ * @brief Abort ongoing transfers (blocking mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Tx and Rx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+ }
+
+ /* Disable the UART DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx stream: use blocking DMA Abort API (no callback) */
+ if (huart->hdmatx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
+ {
+ if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx stream: use blocking DMA Abort API (no callback) */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
+ {
+ if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+
+ /* Reset Tx and Rx transfer counters */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->RxState and huart->gState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Transmit transfer (blocking mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Tx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* Disable the UART DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx stream : use blocking DMA Abort API (no callback) */
+ if (huart->hdmatx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
+ {
+ if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+
+ /* Reset Tx transfer counter */
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Receive transfer (blocking mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Rx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx stream : use blocking DMA Abort API (no callback) */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
+ {
+ if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+
+ /* Reset Rx transfer counter */
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing transfers (Interrupt mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Tx and Rx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
+{
+ uint32_t AbortCplt = 0x01U;
+
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+ }
+
+ /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
+ before any call to DMA Abort functions */
+ /* DMA Tx Handle is valid */
+ if (huart->hdmatx != NULL)
+ {
+ /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
+ Otherwise, set it to NULL */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
+ }
+ else
+ {
+ huart->hdmatx->XferAbortCallback = NULL;
+ }
+ }
+ /* DMA Rx Handle is valid */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
+ Otherwise, set it to NULL */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
+ }
+ else
+ {
+ huart->hdmarx->XferAbortCallback = NULL;
+ }
+ }
+
+ /* Disable the UART DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ /* Disable DMA Tx at UART level */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx stream : use non blocking DMA Abort API (callback) */
+ if (huart->hdmatx != NULL)
+ {
+ /* UART Tx DMA Abort callback has already been initialised :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA TX */
+ if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
+ {
+ huart->hdmatx->XferAbortCallback = NULL;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx stream : use non blocking DMA Abort API (callback) */
+ if (huart->hdmarx != NULL)
+ {
+ /* UART Rx DMA Abort callback has already been initialised :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA RX */
+ if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+ {
+ huart->hdmarx->XferAbortCallback = NULL;
+ AbortCplt = 0x01U;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
+ if (AbortCplt == 0x01U)
+ {
+ /* Reset Tx and Rx transfer counters */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->gState and huart->RxState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort complete callback */
+ huart->AbortCpltCallback(huart);
+#else
+ /* Call legacy weak Abort complete callback */
+ HAL_UART_AbortCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Transmit transfer (Interrupt mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Tx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* Disable the UART DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx stream : use blocking DMA Abort API (no callback) */
+ if (huart->hdmatx != NULL)
+ {
+ /* Set the UART DMA Abort callback :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+ huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
+
+ /* Abort DMA TX */
+ if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
+ {
+ /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
+ huart->hdmatx->XferAbortCallback(huart->hdmatx);
+ }
+ }
+ else
+ {
+ /* Reset Tx transfer counter */
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Transmit Complete Callback */
+ huart->AbortTransmitCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Transmit Complete Callback */
+ HAL_UART_AbortTransmitCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Reset Tx transfer counter */
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Transmit Complete Callback */
+ huart->AbortTransmitCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Transmit Complete Callback */
+ HAL_UART_AbortTransmitCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Receive transfer (Interrupt mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Rx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx stream : use blocking DMA Abort API (no callback) */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
+
+ /* Abort DMA RX */
+ if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+ {
+ /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
+ huart->hdmarx->XferAbortCallback(huart->hdmarx);
+ }
+ }
+ else
+ {
+ /* Reset Rx transfer counter */
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Receive Complete Callback */
+ huart->AbortReceiveCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Receive Complete Callback */
+ HAL_UART_AbortReceiveCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Reset Rx transfer counter */
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Receive Complete Callback */
+ huart->AbortReceiveCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Receive Complete Callback */
+ HAL_UART_AbortReceiveCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles UART interrupt request.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
+{
+ uint32_t isrflags = READ_REG(huart->Instance->SR);
+ uint32_t cr1its = READ_REG(huart->Instance->CR1);
+ uint32_t cr3its = READ_REG(huart->Instance->CR3);
+ uint32_t errorflags = 0x00U;
+ uint32_t dmarequest = 0x00U;
+
+ /* If no error occurs */
+ errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
+ if (errorflags == RESET)
+ {
+ /* UART in mode Receiver -------------------------------------------------*/
+ if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ UART_Receive_IT(huart);
+ return;
+ }
+ }
+
+ /* If some errors occur */
+ if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET)
+ || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
+ {
+ /* UART parity error interrupt occurred ----------------------------------*/
+ if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_PE;
+ }
+
+ /* UART noise error interrupt occurred -----------------------------------*/
+ if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_NE;
+ }
+
+ /* UART frame error interrupt occurred -----------------------------------*/
+ if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_FE;
+ }
+
+ /* UART Over-Run interrupt occurred --------------------------------------*/
+ if (((isrflags & USART_SR_ORE) != RESET) && (((cr1its & USART_CR1_RXNEIE) != RESET)
+ || ((cr3its & USART_CR3_EIE) != RESET)))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_ORE;
+ }
+
+ /* Call UART Error Call back function if need be --------------------------*/
+ if (huart->ErrorCode != HAL_UART_ERROR_NONE)
+ {
+ /* UART in mode Receiver -----------------------------------------------*/
+ if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ UART_Receive_IT(huart);
+ }
+
+ /* If Overrun error occurs, or if any error occurs in DMA mode reception,
+ consider error as blocking */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest)
+ {
+ /* Blocking error : transfer is aborted
+ Set the UART state ready to be able to start again the process,
+ Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
+ UART_EndRxTransfer(huart);
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx stream */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback :
+ will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
+ if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+ {
+ /* Call Directly XferAbortCallback function in case of error */
+ huart->hdmarx->XferAbortCallback(huart->hdmarx);
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Non Blocking error : transfer could go on.
+ Error is notified to user through user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ }
+ }
+ return;
+ } /* End if some error occurs */
+
+ /* Check current reception Mode :
+ If Reception till IDLE event has been selected : */
+ if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ && ((isrflags & USART_SR_IDLE) != 0U)
+ && ((cr1its & USART_CR1_IDLEIE) != 0U))
+ {
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+
+ /* Check if DMA mode is enabled in UART */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ /* DMA mode enabled */
+ /* Check received length : If all expected data are received, do nothing,
+ (DMA cplt callback will be called).
+ Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
+ uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);
+ if ((nb_remaining_rx_data > 0U)
+ && (nb_remaining_rx_data < huart->RxXferSize))
+ {
+ /* Reception is not complete */
+ huart->RxXferCount = nb_remaining_rx_data;
+
+ /* In Normal mode, end DMA xfer and HAL UART Rx process*/
+ if (huart->hdmarx->Init.Mode != DMA_CIRCULAR)
+ {
+ /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
+ in the UART CR3 register */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+ /* Last bytes received, so no need as the abort is immediate */
+ (void)HAL_DMA_Abort(huart->hdmarx);
+ }
+
+ /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+ In this case, Rx Event type is Idle Event */
+ huart->RxEventType = HAL_UART_RXEVENT_IDLE;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Event callback*/
+ huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* If DMA is in Circular mode, Idle event is to be reported to user
+ even if occurring after a Transfer Complete event from DMA */
+ if (nb_remaining_rx_data == huart->RxXferSize)
+ {
+ if (huart->hdmarx->Init.Mode == DMA_CIRCULAR)
+ {
+ /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+ In this case, Rx Event type is Idle Event */
+ huart->RxEventType = HAL_UART_RXEVENT_IDLE;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Event callback*/
+ huart->RxEventCallback(huart, huart->RxXferSize);
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+ }
+ }
+ }
+ return;
+ }
+ else
+ {
+ /* DMA mode not enabled */
+ /* Check received length : If all expected data are received, do nothing.
+ Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
+ uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount;
+ if ((huart->RxXferCount > 0U)
+ && (nb_rx_data > 0U))
+ {
+ /* Disable the UART Parity Error Interrupt and RXNE interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+
+ /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Rx process is completed, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+ /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+ In this case, Rx Event type is Idle Event */
+ huart->RxEventType = HAL_UART_RXEVENT_IDLE;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx complete callback*/
+ huart->RxEventCallback(huart, nb_rx_data);
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, nb_rx_data);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ return;
+ }
+ }
+
+ /* UART in mode Transmitter ------------------------------------------------*/
+ if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
+ {
+ UART_Transmit_IT(huart);
+ return;
+ }
+
+ /* UART in mode Transmitter end --------------------------------------------*/
+ if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
+ {
+ UART_EndTransmit_IT(huart);
+ return;
+ }
+}
+
+/**
+ * @brief Tx Transfer completed callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_TxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx Half Transfer completed callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_TxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_RxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Half Transfer completed callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_RxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART error callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_ErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART Abort Complete callback.
+ * @param huart UART handle.
+ * @retval None
+ */
+__weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UART_AbortCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief UART Abort Complete callback.
+ * @param huart UART handle.
+ * @retval None
+ */
+__weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief UART Abort Receive Complete callback.
+ * @param huart UART handle.
+ * @retval None
+ */
+__weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief Reception Event Callback (Rx event notification called after use of advanced reception service).
+ * @param huart UART handle
+ * @param Size Number of data available in application reception buffer (indicates a position in
+ * reception buffer until which, data are available)
+ * @retval None
+ */
+__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ UNUSED(Size);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UARTEx_RxEventCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
+ * @brief UART control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the UART:
+ (+) HAL_LIN_SendBreak() API can be helpful to transmit the break character.
+ (+) HAL_MultiProcessor_EnterMuteMode() API can be helpful to enter the UART in mute mode.
+ (+) HAL_MultiProcessor_ExitMuteMode() API can be helpful to exit the UART mute mode by software.
+ (+) HAL_HalfDuplex_EnableTransmitter() API to enable the UART transmitter and disables the UART receiver in Half Duplex mode
+ (+) HAL_HalfDuplex_EnableReceiver() API to enable the UART receiver and disables the UART transmitter in Half Duplex mode
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmits break characters.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Send break characters */
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_SBK);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enters the UART in mute mode.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Enable the USART mute mode by setting the RWU bit in the CR1 register */
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RWU);
+
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Exits the UART mute mode: wake up software.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RWU);
+
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables the UART transmitter and disables the UART receiver.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
+{
+ uint32_t tmpreg = 0x00U;
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ tmpreg = huart->Instance->CR1;
+
+ /* Clear TE and RE bits */
+ tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
+
+ /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
+ tmpreg |= (uint32_t)USART_CR1_TE;
+
+ /* Write to USART CR1 */
+ WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables the UART receiver and disables the UART transmitter.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
+{
+ uint32_t tmpreg = 0x00U;
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ tmpreg = huart->Instance->CR1;
+
+ /* Clear TE and RE bits */
+ tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
+
+ /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
+ tmpreg |= (uint32_t)USART_CR1_RE;
+
+ /* Write to USART CR1 */
+ WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions
+ * @brief UART State and Errors functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral State and Errors functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to return the State of
+ UART communication process, return Peripheral Errors occurred during communication
+ process
+ (+) HAL_UART_GetState() API can be helpful to check in run-time the state of the UART peripheral.
+ (+) HAL_UART_GetError() check in run-time errors that could be occurred during communication.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the UART state.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL state
+ */
+HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart)
+{
+ uint32_t temp1 = 0x00U, temp2 = 0x00U;
+ temp1 = huart->gState;
+ temp2 = huart->RxState;
+
+ return (HAL_UART_StateTypeDef)(temp1 | temp2);
+}
+
+/**
+ * @brief Return the UART error code
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART.
+ * @retval UART Error Code
+ */
+uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart)
+{
+ return huart->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Private_Functions UART Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initialize the callbacks to their default values.
+ * @param huart UART handle.
+ * @retval none
+ */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
+{
+ /* Init the UART Callback settings */
+ huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
+ huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
+ huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
+ huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
+ huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
+ huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
+ huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
+ huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
+ huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak RxEventCallback */
+
+}
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+ * @brief DMA UART transmit process complete callback.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+ /* DMA Normal mode*/
+ if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
+ {
+ huart->TxXferCount = 0x00U;
+
+ /* Disable the DMA transfer for transmit request by setting the DMAT bit
+ in the UART CR3 register */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Enable the UART Transmit Complete Interrupt */
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
+
+ }
+ /* DMA Circular mode */
+ else
+ {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Tx complete callback*/
+ huart->TxCpltCallback(huart);
+#else
+ /*Call legacy weak Tx complete callback*/
+ HAL_UART_TxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief DMA UART transmit process half complete callback
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Tx complete callback*/
+ huart->TxHalfCpltCallback(huart);
+#else
+ /*Call legacy weak Tx complete callback*/
+ HAL_UART_TxHalfCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART receive process complete callback.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* DMA Normal mode*/
+ if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
+ {
+ huart->RxXferCount = 0U;
+
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the DMA transfer for the receiver request by setting the DMAR bit
+ in the UART CR3 register */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+ }
+ }
+
+ /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+ In this case, Rx Event type is Transfer Complete */
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ /* Check current reception Mode :
+ If Reception till IDLE event has been selected : use Rx Event callback */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Event callback*/
+ huart->RxEventCallback(huart, huart->RxXferSize);
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* In other cases : use Rx Complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx complete callback*/
+ huart->RxCpltCallback(huart);
+#else
+ /*Call legacy weak Rx complete callback*/
+ HAL_UART_RxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief DMA UART receive process half complete callback
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+ In this case, Rx Event type is Half Transfer */
+ huart->RxEventType = HAL_UART_RXEVENT_HT;
+
+ /* Check current reception Mode :
+ If Reception till IDLE event has been selected : use Rx Event callback */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Event callback*/
+ huart->RxEventCallback(huart, huart->RxXferSize / 2U);
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* In other cases : use Rx Half Complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Half complete callback*/
+ huart->RxHalfCpltCallback(huart);
+#else
+ /*Call legacy weak Rx Half complete callback*/
+ HAL_UART_RxHalfCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief DMA UART communication error callback.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMAError(DMA_HandleTypeDef *hdma)
+{
+ uint32_t dmarequest = 0x00U;
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* Stop UART DMA Tx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
+ if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
+ {
+ huart->TxXferCount = 0x00U;
+ UART_EndTxTransfer(huart);
+ }
+
+ /* Stop UART DMA Rx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
+ {
+ huart->RxXferCount = 0x00U;
+ UART_EndRxTransfer(huart);
+ }
+
+ huart->ErrorCode |= HAL_UART_ERROR_DMA;
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief This function handles UART Communication Timeout. It waits
+ * until a flag is no longer in the specified status.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param Flag specifies the UART flag to check.
+ * @param Status The actual Flag status (SET or RESET).
+ * @param Tickstart Tick start value
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
+ uint32_t Tickstart, uint32_t Timeout)
+{
+ /* Wait until flag is set */
+ while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
+ {
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
+ {
+
+ return HAL_TIMEOUT;
+ }
+
+ if ((READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U) && (Flag != UART_FLAG_TXE) && (Flag != UART_FLAG_TC))
+ {
+ if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) == SET)
+ {
+ /* Clear Overrun Error flag*/
+ __HAL_UART_CLEAR_OREFLAG(huart);
+
+ /* Blocking error : transfer is aborted
+ Set the UART state ready to be able to start again the process,
+ Disable Rx Interrupts if ongoing */
+ UART_EndRxTransfer(huart);
+
+ huart->ErrorCode = HAL_UART_ERROR_ORE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Start Receive operation in interrupt mode.
+ * @note This function could be called by all HAL UART API providing reception in Interrupt mode.
+ * @note When calling this function, parameters validity is considered as already checked,
+ * i.e. Rx State, buffer address, ...
+ * UART Handle is assumed as Locked.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ huart->pRxBuffPtr = pData;
+ huart->RxXferSize = Size;
+ huart->RxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+
+ if (huart->Init.Parity != UART_PARITY_NONE)
+ {
+ /* Enable the UART Parity Error Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_PE);
+ }
+
+ /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
+
+ /* Enable the UART Data Register not empty Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Start Receive operation in DMA mode.
+ * @note This function could be called by all HAL UART API providing reception in DMA mode.
+ * @note When calling this function, parameters validity is considered as already checked,
+ * i.e. Rx State, buffer address, ...
+ * UART Handle is assumed as Locked.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ uint32_t *tmp;
+
+ huart->pRxBuffPtr = pData;
+ huart->RxXferSize = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+
+ /* Set the UART DMA transfer complete callback */
+ huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
+
+ /* Set the UART DMA Half transfer complete callback */
+ huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
+
+ /* Set the DMA error callback */
+ huart->hdmarx->XferErrorCallback = UART_DMAError;
+
+ /* Set the DMA abort callback */
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the DMA stream */
+ tmp = (uint32_t *)&pData;
+ if (HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t *)tmp, Size) != HAL_OK)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ /* Restore huart->RxState to ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_ERROR;
+ }
+ /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
+ __HAL_UART_CLEAR_OREFLAG(huart);
+
+ if (huart->Init.Parity != UART_PARITY_NONE)
+ {
+ /* Enable the UART Parity Error Interrupt */
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ }
+
+ /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the DMA transfer for the receiver request by setting the DMAR bit
+ in the UART CR3 register */
+ ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
+ * @param huart UART handle.
+ * @retval None
+ */
+static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* At end of Tx process, restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+}
+
+/**
+ * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
+ * @param huart UART handle.
+ * @retval None
+ */
+static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+ }
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+}
+
+/**
+ * @brief DMA UART communication abort callback, when initiated by HAL services on Error
+ * (To be called at end of DMA Abort procedure following error occurrence).
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+ huart->RxXferCount = 0x00U;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART Tx communication abort callback, when initiated by user
+ * (To be called at end of DMA Tx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Rx DMA Handle.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if (huart->hdmarx != NULL)
+ {
+ if (huart->hdmarx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->gState and huart->RxState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort complete callback */
+ huart->AbortCpltCallback(huart);
+#else
+ /* Call legacy weak Abort complete callback */
+ HAL_UART_AbortCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART Rx communication abort callback, when initiated by user
+ * (To be called at end of DMA Rx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Tx DMA Handle.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if (huart->hdmatx != NULL)
+ {
+ if (huart->hdmatx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->gState and huart->RxState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort complete callback */
+ huart->AbortCpltCallback(huart);
+#else
+ /* Call legacy weak Abort complete callback */
+ HAL_UART_AbortCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART Tx communication abort callback, when initiated by user by a call to
+ * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
+ * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
+ * and leads to user Tx Abort Complete callback execution).
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Transmit Complete Callback */
+ huart->AbortTransmitCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Transmit Complete Callback */
+ HAL_UART_AbortTransmitCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART Rx communication abort callback, when initiated by user by a call to
+ * HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
+ * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
+ * and leads to user Rx Abort Complete callback execution).
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Receive Complete Callback */
+ huart->AbortReceiveCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Receive Complete Callback */
+ HAL_UART_AbortReceiveCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
+{
+ const uint16_t *tmp;
+
+ /* Check that a Tx process is ongoing */
+ if (huart->gState == HAL_UART_STATE_BUSY_TX)
+ {
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ tmp = (const uint16_t *) huart->pTxBuffPtr;
+ huart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
+ huart->pTxBuffPtr += 2U;
+ }
+ else
+ {
+ huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF);
+ }
+
+ if (--huart->TxXferCount == 0U)
+ {
+ /* Disable the UART Transmit Data Register Empty Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
+
+ /* Enable the UART Transmit Complete Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Wraps up transmission in non blocking mode.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
+{
+ /* Disable the UART Transmit Complete Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_TC);
+
+ /* Tx process is ended, restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Tx complete callback*/
+ huart->TxCpltCallback(huart);
+#else
+ /*Call legacy weak Tx complete callback*/
+ HAL_UART_TxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
+{
+ uint8_t *pdata8bits = NULL;
+ uint16_t *pdata16bits = NULL;
+
+ /* Check that a Rx process is ongoing */
+ if (huart->RxState == HAL_UART_STATE_BUSY_RX)
+ {
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ /* Unused pdata8bits */
+ UNUSED(pdata8bits);
+ pdata16bits = (uint16_t *) huart->pRxBuffPtr;
+ *pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
+ huart->pRxBuffPtr += 2U;
+ }
+ else
+ {
+ pdata8bits = (uint8_t *) huart->pRxBuffPtr;
+ /* Unused pdata16bits */
+ UNUSED(pdata16bits);
+
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
+ }
+ huart->pRxBuffPtr += 1U;
+ }
+
+ if (--huart->RxXferCount == 0U)
+ {
+ /* Disable the UART Data Register not empty Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
+
+ /* Disable the UART Parity Error Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
+
+ /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
+
+ /* Rx process is completed, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* Initialize type of RxEvent to Transfer Complete */
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ /* Check current reception Mode :
+ If Reception till IDLE event has been selected : */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ /* Set reception type to Standard */
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Disable IDLE interrupt */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+ /* Check if IDLE flag is set */
+ if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
+ {
+ /* Clear IDLE flag in ISR */
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+ }
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Event callback*/
+ huart->RxEventCallback(huart, huart->RxXferSize);
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* Standard reception API called */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx complete callback*/
+ huart->RxCpltCallback(huart);
+#else
+ /*Call legacy weak Rx complete callback*/
+ HAL_UART_RxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+
+ return HAL_OK;
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Configures the UART peripheral.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+static void UART_SetConfig(UART_HandleTypeDef *huart)
+{
+ uint32_t tmpreg;
+ uint32_t pclk;
+
+ /* Check the parameters */
+ assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
+ assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
+ assert_param(IS_UART_PARITY(huart->Init.Parity));
+ assert_param(IS_UART_MODE(huart->Init.Mode));
+
+ /*-------------------------- USART CR2 Configuration -----------------------*/
+ /* Configure the UART Stop Bits: Set STOP[13:12] bits
+ according to huart->Init.StopBits value */
+ MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ /* Configure the UART Word Length, Parity and mode:
+ Set the M bits according to huart->Init.WordLength value
+ Set PCE and PS bits according to huart->Init.Parity value
+ Set TE and RE bits according to huart->Init.Mode value
+ Set OVER8 bit according to huart->Init.OverSampling value */
+
+ tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling;
+ MODIFY_REG(huart->Instance->CR1,
+ (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
+ tmpreg);
+
+ /*-------------------------- USART CR3 Configuration -----------------------*/
+ /* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */
+ MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE), huart->Init.HwFlowCtl);
+
+
+#if defined(USART6) && defined(UART9) && defined(UART10)
+ if ((huart->Instance == USART1) || (huart->Instance == USART6) || (huart->Instance == UART9) || (huart->Instance == UART10))
+ {
+ pclk = HAL_RCC_GetPCLK2Freq();
+ }
+#elif defined(USART6)
+ if ((huart->Instance == USART1) || (huart->Instance == USART6))
+ {
+ pclk = HAL_RCC_GetPCLK2Freq();
+ }
+#else
+ if (huart->Instance == USART1)
+ {
+ pclk = HAL_RCC_GetPCLK2Freq();
+ }
+#endif /* USART6 */
+ else
+ {
+ pclk = HAL_RCC_GetPCLK1Freq();
+ }
+ /*-------------------------- USART BRR Configuration ---------------------*/
+ if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING8(pclk, huart->Init.BaudRate);
+ }
+ else
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
+ }
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_UART_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c b/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c
new file mode 100644
index 0000000..435c7c1
--- /dev/null
+++ b/cubemx/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c
@@ -0,0 +1,1061 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_ll_fsmc.c
+ * @author MCD Application Team
+ * @brief FSMC Low Layer HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the Flexible Memory Controller (FSMC) peripheral memories:
+ * + Initialization/de-initialization functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ @verbatim
+ ==============================================================================
+ ##### FSMC peripheral features #####
+ ==============================================================================
+ [..] The Flexible memory controller (FSMC) includes following memory controllers:
+ (+) The NOR/PSRAM memory controller
+ (+) The NAND/PC Card memory controller
+
+ [..] The FSMC functional block makes the interface with synchronous and asynchronous static
+ memories and 16-bit PC memory cards. Its main purposes are:
+ (+) to translate AHB transactions into the appropriate external device protocol
+ (+) to meet the access time requirements of the external memory devices
+
+ [..] All external memories share the addresses, data and control signals with the controller.
+ Each external device is accessed by means of a unique Chip Select. The FSMC performs
+ only one access at a time to an external device.
+ The main features of the FSMC controller are the following:
+ (+) Interface with static-memory mapped devices including:
+ (++) Static random access memory (SRAM)
+ (++) Read-only memory (ROM)
+ (++) NOR Flash memory/OneNAND Flash memory
+ (++) PSRAM (4 memory banks)
+ (++) 16-bit PC Card compatible devices
+ (++) Two banks of NAND Flash memory with ECC hardware to check up to 8 Kbytes of
+ data
+ (+) Independent Chip Select control for each memory bank
+ (+) Independent configuration for each memory bank
+
+ @endverbatim
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+#if defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED) || defined(HAL_PCCARD_MODULE_ENABLED) \
+ || defined(HAL_SRAM_MODULE_ENABLED)
+
+/** @defgroup FSMC_LL FSMC Low Layer
+ * @brief FSMC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup FSMC_LL_Private_Constants FSMC Low Layer Private Constants
+ * @{
+ */
+
+/* ----------------------- FSMC registers bit mask --------------------------- */
+
+#if defined(FSMC_Bank1)
+/* --- BCR Register ---*/
+/* BCR register clear mask */
+
+/* --- BTR Register ---*/
+/* BTR register clear mask */
+#define BTR_CLEAR_MASK ((uint32_t)(FSMC_BTR1_ADDSET | FSMC_BTR1_ADDHLD |\
+ FSMC_BTR1_DATAST | FSMC_BTR1_BUSTURN |\
+ FSMC_BTR1_CLKDIV | FSMC_BTR1_DATLAT |\
+ FSMC_BTR1_ACCMOD))
+
+/* --- BWTR Register ---*/
+/* BWTR register clear mask */
+#define BWTR_CLEAR_MASK ((uint32_t)(FSMC_BWTR1_ADDSET | FSMC_BWTR1_ADDHLD |\
+ FSMC_BWTR1_DATAST | FSMC_BWTR1_BUSTURN |\
+ FSMC_BWTR1_ACCMOD))
+#endif /* FSMC_Bank1 */
+#if defined(FSMC_Bank2_3)
+
+#if defined (FSMC_PCR_PWAITEN)
+/* --- PCR Register ---*/
+/* PCR register clear mask */
+#define PCR_CLEAR_MASK ((uint32_t)(FSMC_PCR_PWAITEN | FSMC_PCR_PBKEN | \
+ FSMC_PCR_PTYP | FSMC_PCR_PWID | \
+ FSMC_PCR_ECCEN | FSMC_PCR_TCLR | \
+ FSMC_PCR_TAR | FSMC_PCR_ECCPS))
+/* --- PMEM Register ---*/
+/* PMEM register clear mask */
+#define PMEM_CLEAR_MASK ((uint32_t)(FSMC_PMEM_MEMSET2 | FSMC_PMEM_MEMWAIT2 |\
+ FSMC_PMEM_MEMHOLD2 | FSMC_PMEM_MEMHIZ2))
+
+/* --- PATT Register ---*/
+/* PATT register clear mask */
+#define PATT_CLEAR_MASK ((uint32_t)(FSMC_PATT_ATTSET2 | FSMC_PATT_ATTWAIT2 |\
+ FSMC_PATT_ATTHOLD2 | FSMC_PATT_ATTHIZ2))
+#else
+/* --- PCR Register ---*/
+/* PCR register clear mask */
+#define PCR_CLEAR_MASK ((uint32_t)(FSMC_PCR2_PWAITEN | FSMC_PCR2_PBKEN | \
+ FSMC_PCR2_PTYP | FSMC_PCR2_PWID | \
+ FSMC_PCR2_ECCEN | FSMC_PCR2_TCLR | \
+ FSMC_PCR2_TAR | FSMC_PCR2_ECCPS))
+/* --- PMEM Register ---*/
+/* PMEM register clear mask */
+#define PMEM_CLEAR_MASK ((uint32_t)(FSMC_PMEM2_MEMSET2 | FSMC_PMEM2_MEMWAIT2 |\
+ FSMC_PMEM2_MEMHOLD2 | FSMC_PMEM2_MEMHIZ2))
+
+/* --- PATT Register ---*/
+/* PATT register clear mask */
+#define PATT_CLEAR_MASK ((uint32_t)(FSMC_PATT2_ATTSET2 | FSMC_PATT2_ATTWAIT2 |\
+ FSMC_PATT2_ATTHOLD2 | FSMC_PATT2_ATTHIZ2))
+
+#endif /* FSMC_PCR_PWAITEN */
+#endif /* FSMC_Bank2_3 */
+#if defined(FSMC_Bank4)
+/* --- PCR Register ---*/
+/* PCR register clear mask */
+#define PCR4_CLEAR_MASK ((uint32_t)(FSMC_PCR4_PWAITEN | FSMC_PCR4_PBKEN | \
+ FSMC_PCR4_PTYP | FSMC_PCR4_PWID | \
+ FSMC_PCR4_ECCEN | FSMC_PCR4_TCLR | \
+ FSMC_PCR4_TAR | FSMC_PCR4_ECCPS))
+/* --- PMEM Register ---*/
+/* PMEM register clear mask */
+#define PMEM4_CLEAR_MASK ((uint32_t)(FSMC_PMEM4_MEMSET4 | FSMC_PMEM4_MEMWAIT4 |\
+ FSMC_PMEM4_MEMHOLD4 | FSMC_PMEM4_MEMHIZ4))
+
+/* --- PATT Register ---*/
+/* PATT register clear mask */
+#define PATT4_CLEAR_MASK ((uint32_t)(FSMC_PATT4_ATTSET4 | FSMC_PATT4_ATTWAIT4 |\
+ FSMC_PATT4_ATTHOLD4 | FSMC_PATT4_ATTHIZ4))
+
+/* --- PIO4 Register ---*/
+/* PIO4 register clear mask */
+#define PIO4_CLEAR_MASK ((uint32_t)(FSMC_PIO4_IOSET4 | FSMC_PIO4_IOWAIT4 | \
+ FSMC_PIO4_IOHOLD4 | FSMC_PIO4_IOHIZ4))
+
+#endif /* FSMC_Bank4 */
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup FSMC_LL_Exported_Functions FSMC Low Layer Exported Functions
+ * @{
+ */
+
+#if defined(FSMC_Bank1)
+
+/** @defgroup FSMC_LL_Exported_Functions_NORSRAM FSMC Low Layer NOR SRAM Exported Functions
+ * @brief NORSRAM Controller functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use NORSRAM device driver #####
+ ==============================================================================
+
+ [..]
+ This driver contains a set of APIs to interface with the FSMC NORSRAM banks in order
+ to run the NORSRAM external devices.
+
+ (+) FSMC NORSRAM bank reset using the function FSMC_NORSRAM_DeInit()
+ (+) FSMC NORSRAM bank control configuration using the function FSMC_NORSRAM_Init()
+ (+) FSMC NORSRAM bank timing configuration using the function FSMC_NORSRAM_Timing_Init()
+ (+) FSMC NORSRAM bank extended timing configuration using the function
+ FSMC_NORSRAM_Extended_Timing_Init()
+ (+) FSMC NORSRAM bank enable/disable write operation using the functions
+ FSMC_NORSRAM_WriteOperation_Enable()/FSMC_NORSRAM_WriteOperation_Disable()
+
+@endverbatim
+ * @{
+ */
+
+/** @defgroup FSMC_LL_NORSRAM_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FSMC NORSRAM interface
+ (+) De-initialize the FSMC NORSRAM interface
+ (+) Configure the FSMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the FSMC_NORSRAM device according to the specified
+ * control parameters in the FSMC_NORSRAM_InitTypeDef
+ * @param Device Pointer to NORSRAM device instance
+ * @param Init Pointer to NORSRAM Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef *Device,
+ const FSMC_NORSRAM_InitTypeDef *Init)
+{
+ uint32_t flashaccess;
+ uint32_t btcr_reg;
+ uint32_t mask;
+
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_NORSRAM_BANK(Init->NSBank));
+ assert_param(IS_FSMC_MUX(Init->DataAddressMux));
+ assert_param(IS_FSMC_MEMORY(Init->MemoryType));
+ assert_param(IS_FSMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth));
+ assert_param(IS_FSMC_BURSTMODE(Init->BurstAccessMode));
+ assert_param(IS_FSMC_WAIT_POLARITY(Init->WaitSignalPolarity));
+#if defined(FSMC_BCR1_WRAPMOD)
+ assert_param(IS_FSMC_WRAP_MODE(Init->WrapMode));
+#endif /* FSMC_BCR1_WRAPMOD */
+ assert_param(IS_FSMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive));
+ assert_param(IS_FSMC_WRITE_OPERATION(Init->WriteOperation));
+ assert_param(IS_FSMC_WAITE_SIGNAL(Init->WaitSignal));
+ assert_param(IS_FSMC_EXTENDED_MODE(Init->ExtendedMode));
+ assert_param(IS_FSMC_ASYNWAIT(Init->AsynchronousWait));
+ assert_param(IS_FSMC_WRITE_BURST(Init->WriteBurst));
+#if defined(FSMC_BCR1_CCLKEN)
+ assert_param(IS_FSMC_CONTINOUS_CLOCK(Init->ContinuousClock));
+#endif /* FSMC_BCR1_CCLKEN */
+#if defined(FSMC_BCR1_WFDIS)
+ assert_param(IS_FSMC_WRITE_FIFO(Init->WriteFifo));
+#endif /* FSMC_BCR1_WFDIS */
+ assert_param(IS_FSMC_PAGESIZE(Init->PageSize));
+
+ /* Disable NORSRAM Device */
+ __FSMC_NORSRAM_DISABLE(Device, Init->NSBank);
+
+ /* Set NORSRAM device control parameters */
+ if (Init->MemoryType == FSMC_MEMORY_TYPE_NOR)
+ {
+ flashaccess = FSMC_NORSRAM_FLASH_ACCESS_ENABLE;
+ }
+ else
+ {
+ flashaccess = FSMC_NORSRAM_FLASH_ACCESS_DISABLE;
+ }
+
+ btcr_reg = (flashaccess | \
+ Init->DataAddressMux | \
+ Init->MemoryType | \
+ Init->MemoryDataWidth | \
+ Init->BurstAccessMode | \
+ Init->WaitSignalPolarity | \
+ Init->WaitSignalActive | \
+ Init->WriteOperation | \
+ Init->WaitSignal | \
+ Init->ExtendedMode | \
+ Init->AsynchronousWait | \
+ Init->WriteBurst);
+
+#if defined(FSMC_BCR1_WRAPMOD)
+ btcr_reg |= Init->WrapMode;
+#endif /* FSMC_BCR1_WRAPMOD */
+#if defined(FSMC_BCR1_CCLKEN)
+ btcr_reg |= Init->ContinuousClock;
+#endif /* FSMC_BCR1_CCLKEN */
+#if defined(FSMC_BCR1_WFDIS)
+ btcr_reg |= Init->WriteFifo;
+#endif /* FSMC_BCR1_WFDIS */
+ btcr_reg |= Init->PageSize;
+
+ mask = (FSMC_BCR1_MBKEN |
+ FSMC_BCR1_MUXEN |
+ FSMC_BCR1_MTYP |
+ FSMC_BCR1_MWID |
+ FSMC_BCR1_FACCEN |
+ FSMC_BCR1_BURSTEN |
+ FSMC_BCR1_WAITPOL |
+ FSMC_BCR1_WAITCFG |
+ FSMC_BCR1_WREN |
+ FSMC_BCR1_WAITEN |
+ FSMC_BCR1_EXTMOD |
+ FSMC_BCR1_ASYNCWAIT |
+ FSMC_BCR1_CBURSTRW);
+
+#if defined(FSMC_BCR1_WRAPMOD)
+ mask |= FSMC_BCR1_WRAPMOD;
+#endif /* FSMC_BCR1_WRAPMOD */
+#if defined(FSMC_BCR1_CCLKEN)
+ mask |= FSMC_BCR1_CCLKEN;
+#endif /* FSMC_BCR1_CCLKEN */
+#if defined(FSMC_BCR1_WFDIS)
+ mask |= FSMC_BCR1_WFDIS;
+#endif /* FSMC_BCR1_WFDIS */
+ mask |= FSMC_BCR1_CPSIZE;
+
+ MODIFY_REG(Device->BTCR[Init->NSBank], mask, btcr_reg);
+
+#if defined(FSMC_BCR1_CCLKEN)
+ /* Configure synchronous mode when Continuous clock is enabled for bank2..4 */
+ if ((Init->ContinuousClock == FSMC_CONTINUOUS_CLOCK_SYNC_ASYNC) && (Init->NSBank != FSMC_NORSRAM_BANK1))
+ {
+ MODIFY_REG(Device->BTCR[FSMC_NORSRAM_BANK1], FSMC_BCR1_CCLKEN, Init->ContinuousClock);
+ }
+#endif /* FSMC_BCR1_CCLKEN */
+#if defined(FSMC_BCR1_WFDIS)
+
+ if (Init->NSBank != FSMC_NORSRAM_BANK1)
+ {
+ /* Configure Write FIFO mode when Write Fifo is enabled for bank2..4 */
+ SET_BIT(Device->BTCR[FSMC_NORSRAM_BANK1], (uint32_t)(Init->WriteFifo));
+ }
+#endif /* FSMC_BCR1_WFDIS */
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitialize the FSMC_NORSRAM peripheral
+ * @param Device Pointer to NORSRAM device instance
+ * @param ExDevice Pointer to NORSRAM extended mode device instance
+ * @param Bank NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_DeInit(FSMC_NORSRAM_TypeDef *Device,
+ FSMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_NORSRAM_EXTENDED_DEVICE(ExDevice));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Disable the FSMC_NORSRAM device */
+ __FSMC_NORSRAM_DISABLE(Device, Bank);
+
+ /* De-initialize the FSMC_NORSRAM device */
+ /* FSMC_NORSRAM_BANK1 */
+ if (Bank == FSMC_NORSRAM_BANK1)
+ {
+ Device->BTCR[Bank] = 0x000030DBU;
+ }
+ /* FSMC_NORSRAM_BANK2, FSMC_NORSRAM_BANK3 or FSMC_NORSRAM_BANK4 */
+ else
+ {
+ Device->BTCR[Bank] = 0x000030D2U;
+ }
+
+ Device->BTCR[Bank + 1U] = 0x0FFFFFFFU;
+ ExDevice->BWTR[Bank] = 0x0FFFFFFFU;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initialize the FSMC_NORSRAM Timing according to the specified
+ * parameters in the FSMC_NORSRAM_TimingTypeDef
+ * @param Device Pointer to NORSRAM device instance
+ * @param Timing Pointer to NORSRAM Timing structure
+ * @param Bank NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef *Device,
+ const FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank)
+{
+#if defined(FSMC_BCR1_CCLKEN)
+ uint32_t tmpr;
+#endif /* FSMC_BCR1_CCLKEN */
+
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
+ assert_param(IS_FSMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
+ assert_param(IS_FSMC_DATASETUP_TIME(Timing->DataSetupTime));
+ assert_param(IS_FSMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
+ assert_param(IS_FSMC_CLK_DIV(Timing->CLKDivision));
+ assert_param(IS_FSMC_DATA_LATENCY(Timing->DataLatency));
+ assert_param(IS_FSMC_ACCESS_MODE(Timing->AccessMode));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Set FSMC_NORSRAM device timing parameters */
+ Device->BTCR[Bank + 1U] =
+ (Timing->AddressSetupTime << FSMC_BTR1_ADDSET_Pos) |
+ (Timing->AddressHoldTime << FSMC_BTR1_ADDHLD_Pos) |
+ (Timing->DataSetupTime << FSMC_BTR1_DATAST_Pos) |
+ (Timing->BusTurnAroundDuration << FSMC_BTR1_BUSTURN_Pos) |
+ ((Timing->CLKDivision - 1U) << FSMC_BTR1_CLKDIV_Pos) |
+ ((Timing->DataLatency - 2U) << FSMC_BTR1_DATLAT_Pos) |
+ Timing->AccessMode;
+
+#if defined(FSMC_BCR1_CCLKEN)
+ /* Configure Clock division value (in NORSRAM bank 1) when continuous clock is enabled */
+ if (HAL_IS_BIT_SET(Device->BTCR[FSMC_NORSRAM_BANK1], FSMC_BCR1_CCLKEN))
+ {
+ tmpr = (uint32_t)(Device->BTCR[FSMC_NORSRAM_BANK1 + 1U] & ~((0x0FU) << FSMC_BTR1_CLKDIV_Pos));
+ tmpr |= (uint32_t)(((Timing->CLKDivision) - 1U) << FSMC_BTR1_CLKDIV_Pos);
+ MODIFY_REG(Device->BTCR[FSMC_NORSRAM_BANK1 + 1U], FSMC_BTR1_CLKDIV, tmpr);
+ }
+
+#endif /* FSMC_BCR1_CCLKEN */
+ return HAL_OK;
+}
+
+/**
+ * @brief Initialize the FSMC_NORSRAM Extended mode Timing according to the specified
+ * parameters in the FSMC_NORSRAM_TimingTypeDef
+ * @param Device Pointer to NORSRAM device instance
+ * @param Timing Pointer to NORSRAM Timing structure
+ * @param Bank NORSRAM bank number
+ * @param ExtendedMode FSMC Extended Mode
+ * This parameter can be one of the following values:
+ * @arg FSMC_EXTENDED_MODE_DISABLE
+ * @arg FSMC_EXTENDED_MODE_ENABLE
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef *Device,
+ const FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank,
+ uint32_t ExtendedMode)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_EXTENDED_MODE(ExtendedMode));
+
+ /* Set NORSRAM device timing register for write configuration, if extended mode is used */
+ if (ExtendedMode == FSMC_EXTENDED_MODE_ENABLE)
+ {
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_EXTENDED_DEVICE(Device));
+ assert_param(IS_FSMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
+ assert_param(IS_FSMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
+ assert_param(IS_FSMC_DATASETUP_TIME(Timing->DataSetupTime));
+ assert_param(IS_FSMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
+ assert_param(IS_FSMC_ACCESS_MODE(Timing->AccessMode));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Set NORSRAM device timing register for write configuration, if extended mode is used */
+ MODIFY_REG(Device->BWTR[Bank], BWTR_CLEAR_MASK, (Timing->AddressSetupTime |
+ ((Timing->AddressHoldTime) << FSMC_BWTR1_ADDHLD_Pos) |
+ ((Timing->DataSetupTime) << FSMC_BWTR1_DATAST_Pos) |
+ Timing->AccessMode |
+ ((Timing->BusTurnAroundDuration) << FSMC_BWTR1_BUSTURN_Pos)));
+ }
+ else
+ {
+ Device->BWTR[Bank] = 0x0FFFFFFFU;
+ }
+
+ return HAL_OK;
+}
+/**
+ * @}
+ */
+
+/** @addtogroup FSMC_LL_NORSRAM_Private_Functions_Group2
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### FSMC_NORSRAM Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the FSMC NORSRAM interface.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables dynamically FSMC_NORSRAM write operation.
+ * @param Device Pointer to NORSRAM device instance
+ * @param Bank NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Enable write operation */
+ SET_BIT(Device->BTCR[Bank], FSMC_WRITE_OPERATION_ENABLE);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FSMC_NORSRAM write operation.
+ * @param Device Pointer to NORSRAM device instance
+ * @param Bank NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Disable write operation */
+ CLEAR_BIT(Device->BTCR[Bank], FSMC_WRITE_OPERATION_ENABLE);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* FSMC_Bank1 */
+
+#if defined(FSMC_Bank2_3)
+
+/** @defgroup FSMC_LL_Exported_Functions_NAND FSMC Low Layer NAND Exported Functions
+ * @brief NAND Controller functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use NAND device driver #####
+ ==============================================================================
+ [..]
+ This driver contains a set of APIs to interface with the FSMC NAND banks in order
+ to run the NAND external devices.
+
+ (+) FSMC NAND bank reset using the function FSMC_NAND_DeInit()
+ (+) FSMC NAND bank control configuration using the function FSMC_NAND_Init()
+ (+) FSMC NAND bank common space timing configuration using the function
+ FSMC_NAND_CommonSpace_Timing_Init()
+ (+) FSMC NAND bank attribute space timing configuration using the function
+ FSMC_NAND_AttributeSpace_Timing_Init()
+ (+) FSMC NAND bank enable/disable ECC correction feature using the functions
+ FSMC_NAND_ECC_Enable()/FSMC_NAND_ECC_Disable()
+ (+) FSMC NAND bank get ECC correction code using the function FSMC_NAND_GetECC()
+
+@endverbatim
+ * @{
+ */
+
+/** @defgroup FSMC_LL_NAND_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FSMC NAND interface
+ (+) De-initialize the FSMC NAND interface
+ (+) Configure the FSMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the FSMC_NAND device according to the specified
+ * control parameters in the FSMC_NAND_HandleTypeDef
+ * @param Device Pointer to NAND device instance
+ * @param Init Pointer to NAND Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_Init(FSMC_NAND_TypeDef *Device, const FSMC_NAND_InitTypeDef *Init)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Init->NandBank));
+ assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature));
+ assert_param(IS_FSMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth));
+ assert_param(IS_FSMC_ECC_STATE(Init->EccComputation));
+ assert_param(IS_FSMC_ECCPAGE_SIZE(Init->ECCPageSize));
+ assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime));
+ assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime));
+
+ /* Set NAND device control parameters */
+ if (Init->NandBank == FSMC_NAND_BANK2)
+ {
+ /* NAND bank 2 registers configuration */
+ MODIFY_REG(Device->PCR2, PCR_CLEAR_MASK, (Init->Waitfeature |
+ FSMC_PCR_MEMORY_TYPE_NAND |
+ Init->MemoryDataWidth |
+ Init->EccComputation |
+ Init->ECCPageSize |
+ ((Init->TCLRSetupTime) << FSMC_PCR2_TCLR_Pos) |
+ ((Init->TARSetupTime) << FSMC_PCR2_TAR_Pos)));
+ }
+ else
+ {
+ /* NAND bank 3 registers configuration */
+ MODIFY_REG(Device->PCR3, PCR_CLEAR_MASK, (Init->Waitfeature |
+ FSMC_PCR_MEMORY_TYPE_NAND |
+ Init->MemoryDataWidth |
+ Init->EccComputation |
+ Init->ECCPageSize |
+ ((Init->TCLRSetupTime) << FSMC_PCR2_TCLR_Pos) |
+ ((Init->TARSetupTime) << FSMC_PCR2_TAR_Pos)));
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FSMC_NAND Common space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device Pointer to NAND device instance
+ * @param Timing Pointer to NAND timing structure
+ * @param Bank NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef *Device,
+ const FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Set FSMC_NAND device timing parameters */
+ if (Bank == FSMC_NAND_BANK2)
+ {
+ /* NAND bank 2 registers configuration */
+ WRITE_REG(Device->PMEM2, (Timing->SetupTime |
+ ((Timing->WaitSetupTime) << FSMC_PMEM2_MEMWAIT2_Pos) |
+ ((Timing->HoldSetupTime) << FSMC_PMEM2_MEMHOLD2_Pos) |
+ ((Timing->HiZSetupTime) << FSMC_PMEM2_MEMHIZ2_Pos)));
+ }
+ else
+ {
+ /* NAND bank 3 registers configuration */
+ WRITE_REG(Device->PMEM3, (Timing->SetupTime |
+ ((Timing->WaitSetupTime) << FSMC_PMEM2_MEMWAIT2_Pos) |
+ ((Timing->HoldSetupTime) << FSMC_PMEM2_MEMHOLD2_Pos) |
+ ((Timing->HiZSetupTime) << FSMC_PMEM2_MEMHIZ2_Pos)));
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FSMC_NAND Attribute space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device Pointer to NAND device instance
+ * @param Timing Pointer to NAND timing structure
+ * @param Bank NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef *Device,
+ const FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Set FSMC_NAND device timing parameters */
+ if (Bank == FSMC_NAND_BANK2)
+ {
+ /* NAND bank 2 registers configuration */
+ WRITE_REG(Device->PATT2, (Timing->SetupTime |
+ ((Timing->WaitSetupTime) << FSMC_PATT2_ATTWAIT2_Pos) |
+ ((Timing->HoldSetupTime) << FSMC_PATT2_ATTHOLD2_Pos) |
+ ((Timing->HiZSetupTime) << FSMC_PATT2_ATTHIZ2_Pos)));
+ }
+ else
+ {
+ /* NAND bank 3 registers configuration */
+ WRITE_REG(Device->PATT3, (Timing->SetupTime |
+ ((Timing->WaitSetupTime) << FSMC_PATT2_ATTWAIT2_Pos) |
+ ((Timing->HoldSetupTime) << FSMC_PATT2_ATTHOLD2_Pos) |
+ ((Timing->HiZSetupTime) << FSMC_PATT2_ATTHIZ2_Pos)));
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the FSMC_NAND device
+ * @param Device Pointer to NAND device instance
+ * @param Bank NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_DeInit(FSMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Disable the NAND Bank */
+ __FSMC_NAND_DISABLE(Device, Bank);
+
+ /* De-initialize the NAND Bank */
+ if (Bank == FSMC_NAND_BANK2)
+ {
+ /* Set the FSMC_NAND_BANK2 registers to their reset values */
+ WRITE_REG(Device->PCR2, 0x00000018U);
+ WRITE_REG(Device->SR2, 0x00000040U);
+ WRITE_REG(Device->PMEM2, 0xFCFCFCFCU);
+ WRITE_REG(Device->PATT2, 0xFCFCFCFCU);
+ }
+ /* FSMC_Bank3_NAND */
+ else
+ {
+ /* Set the FSMC_NAND_BANK3 registers to their reset values */
+ WRITE_REG(Device->PCR3, 0x00000018U);
+ WRITE_REG(Device->SR3, 0x00000040U);
+ WRITE_REG(Device->PMEM3, 0xFCFCFCFCU);
+ WRITE_REG(Device->PATT3, 0xFCFCFCFCU);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup HAL_FSMC_NAND_Group2 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### FSMC_NAND Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the FSMC NAND interface.
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Enables dynamically FSMC_NAND ECC feature.
+ * @param Device Pointer to NAND device instance
+ * @param Bank NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Enable ECC feature */
+ if (Bank == FSMC_NAND_BANK2)
+ {
+ SET_BIT(Device->PCR2, FSMC_PCR2_ECCEN);
+ }
+ else
+ {
+ SET_BIT(Device->PCR3, FSMC_PCR2_ECCEN);
+ }
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Disables dynamically FSMC_NAND ECC feature.
+ * @param Device Pointer to NAND device instance
+ * @param Bank NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Disable ECC feature */
+ if (Bank == FSMC_NAND_BANK2)
+ {
+ CLEAR_BIT(Device->PCR2, FSMC_PCR2_ECCEN);
+ }
+ else
+ {
+ CLEAR_BIT(Device->PCR3, FSMC_PCR2_ECCEN);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FSMC_NAND ECC feature.
+ * @param Device Pointer to NAND device instance
+ * @param ECCval Pointer to ECC value
+ * @param Bank NAND bank number
+ * @param Timeout Timeout wait value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_GetECC(const FSMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank,
+ uint32_t Timeout)
+{
+ uint32_t tickstart;
+
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait until FIFO is empty */
+ while (__FSMC_NAND_GET_FLAG(Device, Bank, FSMC_FLAG_FEMPT) == RESET)
+ {
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ if (Bank == FSMC_NAND_BANK2)
+ {
+ /* Get the ECCR2 register value */
+ *ECCval = (uint32_t)Device->ECCR2;
+ }
+ else
+ {
+ /* Get the ECCR3 register value */
+ *ECCval = (uint32_t)Device->ECCR3;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+#endif /* FSMC_Bank2_3 */
+
+#if defined(FSMC_Bank4)
+
+/** @addtogroup FSMC_LL_PCCARD
+ * @brief PCCARD Controller functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use PCCARD device driver #####
+ ==============================================================================
+ [..]
+ This driver contains a set of APIs to interface with the FSMC PCCARD bank in order
+ to run the PCCARD/compact flash external devices.
+
+ (+) FSMC PCCARD bank reset using the function FSMC_PCCARD_DeInit()
+ (+) FSMC PCCARD bank control configuration using the function FSMC_PCCARD_Init()
+ (+) FSMC PCCARD bank common space timing configuration using the function
+ FSMC_PCCARD_CommonSpace_Timing_Init()
+ (+) FSMC PCCARD bank attribute space timing configuration using the function
+ FSMC_PCCARD_AttributeSpace_Timing_Init()
+ (+) FSMC PCCARD bank IO space timing configuration using the function
+ FSMC_PCCARD_IOSpace_Timing_Init()
+@endverbatim
+ * @{
+ */
+
+/** @addtogroup FSMC_LL_PCCARD_Private_Functions_Group1
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FSMC PCCARD interface
+ (+) De-initialize the FSMC PCCARD interface
+ (+) Configure the FSMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the FSMC_PCCARD device according to the specified
+ * control parameters in the FSMC_PCCARD_HandleTypeDef
+ * @param Device Pointer to PCCARD device instance
+ * @param Init Pointer to PCCARD Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef *Device, const FSMC_PCCARD_InitTypeDef *Init)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+#if defined(FSMC_Bank2_3)
+ assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature));
+ assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime));
+ assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime));
+#endif /* FSMC_Bank2_3 */
+
+ /* Set FSMC_PCCARD device control parameters */
+ MODIFY_REG(Device->PCR4,
+ (FSMC_PCR4_PTYP |
+ FSMC_PCR4_PWAITEN |
+ FSMC_PCR4_PWID |
+ FSMC_PCR4_TCLR |
+ FSMC_PCR4_TAR),
+ (FSMC_PCR_MEMORY_TYPE_PCCARD |
+ Init->Waitfeature |
+ FSMC_NAND_PCC_MEM_BUS_WIDTH_16 |
+ (Init->TCLRSetupTime << FSMC_PCR4_TCLR_Pos) |
+ (Init->TARSetupTime << FSMC_PCR4_TAR_Pos)));
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FSMC_PCCARD Common space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device Pointer to PCCARD device instance
+ * @param Timing Pointer to PCCARD timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device,
+ const FSMC_NAND_PCC_TimingTypeDef *Timing)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+#if defined(FSMC_Bank2_3)
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+#endif /* FSMC_Bank2_3 */
+
+ /* Set PCCARD timing parameters */
+ WRITE_REG(Device->PMEM4, (Timing->SetupTime |
+ ((Timing->WaitSetupTime) << FSMC_PMEM4_MEMWAIT4_Pos) |
+ ((Timing->HoldSetupTime) << FSMC_PMEM4_MEMHOLD4_Pos) |
+ ((Timing->HiZSetupTime) << FSMC_PMEM4_MEMHIZ4_Pos)));
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FSMC_PCCARD Attribute space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device Pointer to PCCARD device instance
+ * @param Timing Pointer to PCCARD timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device,
+ const FSMC_NAND_PCC_TimingTypeDef *Timing)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+#if defined(FSMC_Bank2_3)
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+#endif /* FSMC_Bank2_3 */
+
+ /* Set PCCARD timing parameters */
+ WRITE_REG(Device->PATT4, (Timing->SetupTime |
+ ((Timing->WaitSetupTime) << FSMC_PATT4_ATTWAIT4_Pos) |
+ ((Timing->HoldSetupTime) << FSMC_PATT4_ATTHOLD4_Pos) |
+ ((Timing->HiZSetupTime) << FSMC_PATT4_ATTHIZ4_Pos)));
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FSMC_PCCARD IO space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device Pointer to PCCARD device instance
+ * @param Timing Pointer to PCCARD timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device,
+ const FSMC_NAND_PCC_TimingTypeDef *Timing)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+#if defined(FSMC_Bank2_3)
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+#endif /* FSMC_Bank2_3 */
+
+ /* Set FSMC_PCCARD device timing parameters */
+ WRITE_REG(Device->PIO4, (Timing->SetupTime |
+ (Timing->WaitSetupTime << FSMC_PIO4_IOWAIT4_Pos) |
+ (Timing->HoldSetupTime << FSMC_PIO4_IOHOLD4_Pos) |
+ (Timing->HiZSetupTime << FSMC_PIO4_IOHIZ4_Pos)));
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the FSMC_PCCARD device
+ * @param Device Pointer to PCCARD device instance
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef *Device)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+
+ /* Disable the FSMC_PCCARD device */
+ __FSMC_PCCARD_DISABLE(Device);
+
+ /* De-initialize the FSMC_PCCARD device */
+ Device->PCR4 = 0x00000018U;
+ Device->SR4 = 0x00000040U;
+ Device->PMEM4 = 0xFCFCFCFCU;
+ Device->PATT4 = 0xFCFCFCFCU;
+ Device->PIO4 = 0xFCFCFCFCU;
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+#endif /* FSMC_Bank4 */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_NOR_MODULE_ENABLED */
+/**
+ * @}
+ */
+/**
+ * @}
+ */
diff --git a/cubemx/EWARM/cubemx.ewp b/cubemx/EWARM/cubemx.ewp
index e33458d..4c8d19a 100644
--- a/cubemx/EWARM/cubemx.ewp
+++ b/cubemx/EWARM/cubemx.ewp
@@ -1078,38 +1078,14 @@
User
- $PROJ_DIR$/../C:/RT-ThreadStudio/workspace/828/cubemx/Src/main.c
+ $PROJ_DIR$/../Src/main.c
- $PROJ_DIR$/../C:/RT-ThreadStudio/workspace/828/cubemx/Src/stm32f4xx_it.c
+ $PROJ_DIR$/../Src/stm32f4xx_it.c
- $PROJ_DIR$/../C:/RT-ThreadStudio/workspace/828/cubemx/Src/stm32f4xx_hal_msp.c
+ $PROJ_DIR$/../Src/stm32f4xx_hal_msp.c
-
- C:
-
- RT-ThreadStudio
-
- workspace
-
- 828
-
- cubemx
-
- $PROJ_DIR$/../C:/RT-ThreadStudio/workspace/828/cubemx/Src/main.c
-
-
- $PROJ_DIR$/../C:/RT-ThreadStudio/workspace/828/cubemx/Src/stm32f4xx_it.c
-
-
- $PROJ_DIR$/../C:/RT-ThreadStudio/workspace/828/cubemx/Src/stm32f4xx_hal_msp.c
-
-
-
-
-
-
@@ -1117,13 +1093,19 @@
STM32F4xx_HAL_Driver
- $PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c
+ $PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c
- $PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c
+ $PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nor.c
- $PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_mmc.c
+ $PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c
+
+
+ $PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c
+
+
+ $PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pccard.c
$PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c
@@ -1164,6 +1146,18 @@
$PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c
+
+ $PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c
+
+
+ $PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c
+
+
+ $PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_mmc.c
+
+
+ $PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c
+
CMSIS
diff --git a/cubemx/Inc/stm32f4xx_hal_conf.h b/cubemx/Inc/stm32f4xx_hal_conf.h
index d479be6..2ed55a6 100644
--- a/cubemx/Inc/stm32f4xx_hal_conf.h
+++ b/cubemx/Inc/stm32f4xx_hal_conf.h
@@ -50,7 +50,7 @@
/* #define HAL_NAND_MODULE_ENABLED */
/* #define HAL_NOR_MODULE_ENABLED */
/* #define HAL_PCCARD_MODULE_ENABLED */
-/* #define HAL_SRAM_MODULE_ENABLED */
+#define HAL_SRAM_MODULE_ENABLED
/* #define HAL_SDRAM_MODULE_ENABLED */
/* #define HAL_HASH_MODULE_ENABLED */
/* #define HAL_I2C_MODULE_ENABLED */
diff --git a/cubemx/Src/main.c b/cubemx/Src/main.c
index 497ee02..55d22a5 100644
--- a/cubemx/Src/main.c
+++ b/cubemx/Src/main.c
@@ -42,6 +42,10 @@
/* Private variables ---------------------------------------------------------*/
SD_HandleTypeDef hsd;
+UART_HandleTypeDef huart2;
+
+SRAM_HandleTypeDef hsram1;
+
/* USER CODE BEGIN PV */
/* USER CODE END PV */
@@ -50,6 +54,8 @@ SD_HandleTypeDef hsd;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SDIO_SD_Init(void);
+static void MX_USART2_UART_Init(void);
+static void MX_FSMC_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
@@ -89,6 +95,8 @@ __WEAK int main(void)
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SDIO_SD_Init();
+ MX_USART2_UART_Init();
+ MX_FSMC_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
@@ -186,6 +194,39 @@ static void MX_SDIO_SD_Init(void)
}
+/**
+ * @brief USART2 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_USART2_UART_Init(void)
+{
+
+ /* USER CODE BEGIN USART2_Init 0 */
+
+ /* USER CODE END USART2_Init 0 */
+
+ /* USER CODE BEGIN USART2_Init 1 */
+
+ /* USER CODE END USART2_Init 1 */
+ huart2.Instance = USART2;
+ huart2.Init.BaudRate = 115200;
+ huart2.Init.WordLength = UART_WORDLENGTH_8B;
+ huart2.Init.StopBits = UART_STOPBITS_1;
+ huart2.Init.Parity = UART_PARITY_NONE;
+ huart2.Init.Mode = UART_MODE_TX_RX;
+ huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+ huart2.Init.OverSampling = UART_OVERSAMPLING_16;
+ if (HAL_UART_Init(&huart2) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /* USER CODE BEGIN USART2_Init 2 */
+
+ /* USER CODE END USART2_Init 2 */
+
+}
+
/**
* @brief GPIO Initialization Function
* @param None
@@ -198,14 +239,69 @@ static void MX_GPIO_Init(void)
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
- __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
+/* FSMC initialization function */
+static void MX_FSMC_Init(void)
+{
+
+ /* USER CODE BEGIN FSMC_Init 0 */
+
+ /* USER CODE END FSMC_Init 0 */
+
+ FSMC_NORSRAM_TimingTypeDef Timing = {0};
+
+ /* USER CODE BEGIN FSMC_Init 1 */
+
+ /* USER CODE END FSMC_Init 1 */
+
+ /** Perform the SRAM1 memory initialization sequence
+ */
+ hsram1.Instance = FSMC_NORSRAM_DEVICE;
+ hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
+ /* hsram1.Init */
+ hsram1.Init.NSBank = FSMC_NORSRAM_BANK1;
+ hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
+ hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
+ hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
+ hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
+ hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
+ hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
+ hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
+ hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
+ hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
+ hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;
+ hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
+ hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
+ hsram1.Init.PageSize = FSMC_PAGE_SIZE_NONE;
+ /* Timing */
+ Timing.AddressSetupTime = 15;
+ Timing.AddressHoldTime = 15;
+ Timing.DataSetupTime = 255;
+ Timing.BusTurnAroundDuration = 15;
+ Timing.CLKDivision = 16;
+ Timing.DataLatency = 17;
+ Timing.AccessMode = FSMC_ACCESS_MODE_A;
+ /* ExtTiming */
+
+ if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
+ {
+ Error_Handler( );
+ }
+
+ /* USER CODE BEGIN FSMC_Init 2 */
+
+ /* USER CODE END FSMC_Init 2 */
+}
+
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
diff --git a/cubemx/Src/stm32f4xx_hal_msp.c b/cubemx/Src/stm32f4xx_hal_msp.c
index cf6b2b5..c78e8d7 100644
--- a/cubemx/Src/stm32f4xx_hal_msp.c
+++ b/cubemx/Src/stm32f4xx_hal_msp.c
@@ -163,6 +163,200 @@ void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd)
}
+/**
+ * @brief UART MSP Initialization
+ * This function configures the hardware resources used in this example
+ * @param huart: UART handle pointer
+ * @retval None
+ */
+void HAL_UART_MspInit(UART_HandleTypeDef* huart)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(huart->Instance==USART2)
+ {
+ /* USER CODE BEGIN USART2_MspInit 0 */
+
+ /* USER CODE END USART2_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_USART2_CLK_ENABLE();
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ /**USART2 GPIO Configuration
+ PA2 ------> USART2_TX
+ PA3 ------> USART2_RX
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN USART2_MspInit 1 */
+
+ /* USER CODE END USART2_MspInit 1 */
+
+ }
+
+}
+
+/**
+ * @brief UART MSP De-Initialization
+ * This function freeze the hardware resources used in this example
+ * @param huart: UART handle pointer
+ * @retval None
+ */
+void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
+{
+ if(huart->Instance==USART2)
+ {
+ /* USER CODE BEGIN USART2_MspDeInit 0 */
+
+ /* USER CODE END USART2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_USART2_CLK_DISABLE();
+
+ /**USART2 GPIO Configuration
+ PA2 ------> USART2_TX
+ PA3 ------> USART2_RX
+ */
+ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
+
+ /* USER CODE BEGIN USART2_MspDeInit 1 */
+
+ /* USER CODE END USART2_MspDeInit 1 */
+ }
+
+}
+
+static uint32_t FSMC_Initialized = 0;
+
+static void HAL_FSMC_MspInit(void){
+ /* USER CODE BEGIN FSMC_MspInit 0 */
+
+ /* USER CODE END FSMC_MspInit 0 */
+ GPIO_InitTypeDef GPIO_InitStruct ={0};
+ if (FSMC_Initialized) {
+ return;
+ }
+ FSMC_Initialized = 1;
+
+ /* Peripheral clock enable */
+ __HAL_RCC_FSMC_CLK_ENABLE();
+
+ /** FSMC GPIO Configuration
+ PE7 ------> FSMC_D4
+ PE8 ------> FSMC_D5
+ PE9 ------> FSMC_D6
+ PE10 ------> FSMC_D7
+ PE11 ------> FSMC_D8
+ PE12 ------> FSMC_D9
+ PE13 ------> FSMC_D10
+ PE14 ------> FSMC_D11
+ PE15 ------> FSMC_D12
+ PD8 ------> FSMC_D13
+ PD9 ------> FSMC_D14
+ PD10 ------> FSMC_D15
+ PD11 ------> FSMC_A16
+ PD14 ------> FSMC_D0
+ PD15 ------> FSMC_D1
+ PD0 ------> FSMC_D2
+ PD1 ------> FSMC_D3
+ PD4 ------> FSMC_NOE
+ PD5 ------> FSMC_NWE
+ PD7 ------> FSMC_NE1
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
+ |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
+ |GPIO_PIN_15;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
+ |GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1
+ |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;
+ HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN FSMC_MspInit 1 */
+
+ /* USER CODE END FSMC_MspInit 1 */
+}
+
+void HAL_SRAM_MspInit(SRAM_HandleTypeDef* hsram){
+ /* USER CODE BEGIN SRAM_MspInit 0 */
+
+ /* USER CODE END SRAM_MspInit 0 */
+ HAL_FSMC_MspInit();
+ /* USER CODE BEGIN SRAM_MspInit 1 */
+
+ /* USER CODE END SRAM_MspInit 1 */
+}
+
+static uint32_t FSMC_DeInitialized = 0;
+
+static void HAL_FSMC_MspDeInit(void){
+ /* USER CODE BEGIN FSMC_MspDeInit 0 */
+
+ /* USER CODE END FSMC_MspDeInit 0 */
+ if (FSMC_DeInitialized) {
+ return;
+ }
+ FSMC_DeInitialized = 1;
+ /* Peripheral clock enable */
+ __HAL_RCC_FSMC_CLK_DISABLE();
+
+ /** FSMC GPIO Configuration
+ PE7 ------> FSMC_D4
+ PE8 ------> FSMC_D5
+ PE9 ------> FSMC_D6
+ PE10 ------> FSMC_D7
+ PE11 ------> FSMC_D8
+ PE12 ------> FSMC_D9
+ PE13 ------> FSMC_D10
+ PE14 ------> FSMC_D11
+ PE15 ------> FSMC_D12
+ PD8 ------> FSMC_D13
+ PD9 ------> FSMC_D14
+ PD10 ------> FSMC_D15
+ PD11 ------> FSMC_A16
+ PD14 ------> FSMC_D0
+ PD15 ------> FSMC_D1
+ PD0 ------> FSMC_D2
+ PD1 ------> FSMC_D3
+ PD4 ------> FSMC_NOE
+ PD5 ------> FSMC_NWE
+ PD7 ------> FSMC_NE1
+ */
+ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
+ |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
+ |GPIO_PIN_15);
+
+ HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
+ |GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1
+ |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7);
+
+ /* USER CODE BEGIN FSMC_MspDeInit 1 */
+
+ /* USER CODE END FSMC_MspDeInit 1 */
+}
+
+void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef* hsram){
+ /* USER CODE BEGIN SRAM_MspDeInit 0 */
+
+ /* USER CODE END SRAM_MspDeInit 0 */
+ HAL_FSMC_MspDeInit();
+ /* USER CODE BEGIN SRAM_MspDeInit 1 */
+
+ /* USER CODE END SRAM_MspDeInit 1 */
+}
+
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
diff --git a/cubemx/cubemx.ioc b/cubemx/cubemx.ioc
index 6026b8e..dfc2fef 100644
--- a/cubemx/cubemx.ioc
+++ b/cubemx/cubemx.ioc
@@ -7,21 +7,45 @@ GPIO.groupedBy=
KeepUserPlacement=false
Mcu.CPN=STM32F407ZGT6
Mcu.Family=STM32F4
-Mcu.IP0=NVIC
-Mcu.IP1=RCC
-Mcu.IP2=SDIO
-Mcu.IP3=SYS
-Mcu.IPNb=4
+Mcu.IP0=FSMC
+Mcu.IP1=NVIC
+Mcu.IP2=RCC
+Mcu.IP3=SDIO
+Mcu.IP4=SYS
+Mcu.IP5=USART2
+Mcu.IPNb=6
Mcu.Name=STM32F407Z(E-G)Tx
Mcu.Package=LQFP144
-Mcu.Pin0=PC8
-Mcu.Pin1=PC9
-Mcu.Pin2=PC10
-Mcu.Pin3=PC11
-Mcu.Pin4=PC12
-Mcu.Pin5=PD2
-Mcu.Pin6=VP_SYS_VS_Systick
-Mcu.PinsNb=7
+Mcu.Pin0=PA2
+Mcu.Pin1=PA3
+Mcu.Pin10=PE15
+Mcu.Pin11=PD8
+Mcu.Pin12=PD9
+Mcu.Pin13=PD10
+Mcu.Pin14=PD11
+Mcu.Pin15=PD14
+Mcu.Pin16=PD15
+Mcu.Pin17=PC8
+Mcu.Pin18=PC9
+Mcu.Pin19=PC10
+Mcu.Pin2=PE7
+Mcu.Pin20=PC11
+Mcu.Pin21=PC12
+Mcu.Pin22=PD0
+Mcu.Pin23=PD1
+Mcu.Pin24=PD2
+Mcu.Pin25=PD4
+Mcu.Pin26=PD5
+Mcu.Pin27=PD7
+Mcu.Pin28=VP_SYS_VS_Systick
+Mcu.Pin3=PE8
+Mcu.Pin4=PE9
+Mcu.Pin5=PE10
+Mcu.Pin6=PE11
+Mcu.Pin7=PE12
+Mcu.Pin8=PE13
+Mcu.Pin9=PE14
+Mcu.PinsNb=29
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F407ZGTx
@@ -38,6 +62,10 @@ NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+PA2.Mode=Asynchronous
+PA2.Signal=USART2_TX
+PA3.Mode=Asynchronous
+PA3.Signal=USART2_RX
PC10.Mode=SD_4_bits_Wide_bus
PC10.Signal=SDIO_D2
PC11.Mode=SD_4_bits_Wide_bus
@@ -48,8 +76,29 @@ PC8.Mode=SD_4_bits_Wide_bus
PC8.Signal=SDIO_D0
PC9.Mode=SD_4_bits_Wide_bus
PC9.Signal=SDIO_D1
+PD0.Signal=FSMC_D2_DA2
+PD1.Signal=FSMC_D3_DA3
+PD10.Signal=FSMC_D15_DA15
+PD11.Signal=FSMC_A16_CLE
+PD14.Signal=FSMC_D0_DA0
+PD15.Signal=FSMC_D1_DA1
PD2.Mode=SD_4_bits_Wide_bus
PD2.Signal=SDIO_CMD
+PD4.Signal=FSMC_NOE
+PD5.Signal=FSMC_NWE
+PD7.Mode=NorPsramChipSelect1_1
+PD7.Signal=FSMC_NE1
+PD8.Signal=FSMC_D13_DA13
+PD9.Signal=FSMC_D14_DA14
+PE10.Signal=FSMC_D7_DA7
+PE11.Signal=FSMC_D8_DA8
+PE12.Signal=FSMC_D9_DA9
+PE13.Signal=FSMC_D10_DA10
+PE14.Signal=FSMC_D11_DA11
+PE15.Signal=FSMC_D12_DA12
+PE7.Signal=FSMC_D4_DA4
+PE8.Signal=FSMC_D5_DA5
+PE9.Signal=FSMC_D6_DA6
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
@@ -82,7 +131,7 @@ ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false
-ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false
+ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_SDIO_SD_Init-SDIO-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true,5-MX_FSMC_Init-FSMC-false-HAL-true
RCC.48MHZClocksFreq_Value=48000000
RCC.AHBFreq_Value=168000000
RCC.APB1CLKDivider=RCC_HCLK_DIV4
@@ -116,6 +165,46 @@ RCC.VCOI2SOutputFreq_Value=384000000
RCC.VCOInputFreq_Value=2000000
RCC.VCOOutputFreq_Value=336000000
RCC.VcooutputI2S=192000000
+SH.FSMC_A16_CLE.0=FSMC_A16,A16_1
+SH.FSMC_A16_CLE.ConfNb=1
+SH.FSMC_D0_DA0.0=FSMC_D0,16b-d1
+SH.FSMC_D0_DA0.ConfNb=1
+SH.FSMC_D10_DA10.0=FSMC_D10,16b-d1
+SH.FSMC_D10_DA10.ConfNb=1
+SH.FSMC_D11_DA11.0=FSMC_D11,16b-d1
+SH.FSMC_D11_DA11.ConfNb=1
+SH.FSMC_D12_DA12.0=FSMC_D12,16b-d1
+SH.FSMC_D12_DA12.ConfNb=1
+SH.FSMC_D13_DA13.0=FSMC_D13,16b-d1
+SH.FSMC_D13_DA13.ConfNb=1
+SH.FSMC_D14_DA14.0=FSMC_D14,16b-d1
+SH.FSMC_D14_DA14.ConfNb=1
+SH.FSMC_D15_DA15.0=FSMC_D15,16b-d1
+SH.FSMC_D15_DA15.ConfNb=1
+SH.FSMC_D1_DA1.0=FSMC_D1,16b-d1
+SH.FSMC_D1_DA1.ConfNb=1
+SH.FSMC_D2_DA2.0=FSMC_D2,16b-d1
+SH.FSMC_D2_DA2.ConfNb=1
+SH.FSMC_D3_DA3.0=FSMC_D3,16b-d1
+SH.FSMC_D3_DA3.ConfNb=1
+SH.FSMC_D4_DA4.0=FSMC_D4,16b-d1
+SH.FSMC_D4_DA4.ConfNb=1
+SH.FSMC_D5_DA5.0=FSMC_D5,16b-d1
+SH.FSMC_D5_DA5.ConfNb=1
+SH.FSMC_D6_DA6.0=FSMC_D6,16b-d1
+SH.FSMC_D6_DA6.ConfNb=1
+SH.FSMC_D7_DA7.0=FSMC_D7,16b-d1
+SH.FSMC_D7_DA7.ConfNb=1
+SH.FSMC_D8_DA8.0=FSMC_D8,16b-d1
+SH.FSMC_D8_DA8.ConfNb=1
+SH.FSMC_D9_DA9.0=FSMC_D9,16b-d1
+SH.FSMC_D9_DA9.ConfNb=1
+SH.FSMC_NOE.0=FSMC_NOE,Lcd1
+SH.FSMC_NOE.ConfNb=1
+SH.FSMC_NWE.0=FSMC_NWE,Lcd1
+SH.FSMC_NWE.ConfNb=1
+USART2.IPParameters=VirtualMode
+USART2.VirtualMode=VM_ASYNC
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
board=custom
diff --git a/drivers/board.c b/drivers/board.c
index 370caac..e9d093a 100644
--- a/drivers/board.c
+++ b/drivers/board.c
@@ -34,3 +34,4 @@ RT_WEAK void rt_hw_board_init()
#endif
}
+
diff --git a/exclude_list.json b/exclude_list.json
new file mode 100644
index 0000000..9d4bede
--- /dev/null
+++ b/exclude_list.json
@@ -0,0 +1 @@
+[{"config_name":"Debug","exclude_files":["applications/LVGL"]}]
\ No newline at end of file
diff --git a/packages/lv_music_demo-latest b/packages/lv_music_demo-latest
new file mode 160000
--- /dev/null
+++ b/packages/lv_music_demo-latest
@@ -0,0 +1 @@
+Subproject commit 0000000000000000000000000000000000000000
diff --git a/packages/packages.dbsqlite b/packages/packages.dbsqlite
index 3b94437..4ffb657 100644
Binary files a/packages/packages.dbsqlite and b/packages/packages.dbsqlite differ
diff --git a/packages/pkgs.json b/packages/pkgs.json
index 9abb50a..1478b3b 100644
--- a/packages/pkgs.json
+++ b/packages/pkgs.json
@@ -4,6 +4,16 @@
"ver": "v1.7.17",
"name": "CJSON"
},
+ {
+ "path": "/packages/multimedia/LVGL/LVGL",
+ "ver": "v8.3.0",
+ "name": "LVGL"
+ },
+ {
+ "path": "/packages/multimedia/LVGL/gui_guider_demo",
+ "ver": "latest",
+ "name": "GUI_GUIDER_DEMO"
+ },
{
"path": "/packages/system/sqlite",
"ver": "v3.19.3",
diff --git a/rtconfig.h b/rtconfig.h
index 4cfa15d..6025a4a 100644
--- a/rtconfig.h
+++ b/rtconfig.h
@@ -131,14 +131,22 @@
#define RT_USING_POSIX_FS
#define RT_USING_POSIX_DEVIO
+#define RT_USING_POSIX_POLL
+#define RT_USING_POSIX_DELAY
+#define RT_USING_POSIX_CLOCK
/* Interprocess Communication (IPC) */
+#define RT_USING_POSIX_PIPE
+#define RT_USING_POSIX_PIPE_SIZE 512
+#define RT_USING_POSIX_MESSAGE_QUEUE
+#define RT_USING_POSIX_MESSAGE_SEMAPHORE
/* Socket is in the 'Network' category */
/* end of Interprocess Communication (IPC) */
/* end of POSIX (Portable Operating System Interface) layer */
+#define RT_USING_CPLUSPLUS
/* end of C/C++ and POSIX layer */
/* Network */
@@ -236,8 +244,6 @@
#define PKG_SQLITE_SQL_MAX_LEN 1024
#define PKG_SQLITE_DB_NAME_MAX_LEN 64
#define PKG_USING_SQLITE_V3193
-#define PKG_USING_UART_FRAMEWORK
-#define PKG_USING_UART_FRAMEWORK_LATEST_VERSION
/* end of system packages */
/* peripheral libraries and drivers */
diff --git a/rtconfig_preinc.h b/rtconfig_preinc.h
index beb5089..bb88aa5 100644
--- a/rtconfig_preinc.h
+++ b/rtconfig_preinc.h
@@ -9,5 +9,6 @@
#define RT_USING_NEWLIB
#define _POSIX_C_SOURCE 1
#define __RTTHREAD__
+#define _REENT_SMALL
#endif /*RTCONFIG_PREINC_H__*/