/******************************************************************************
* @file: core_cm3.h
* @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Header File
* @version: V1.20
* @date: 22. May 2009
*----------------------------------------------------------------------------
*
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* ARM Limited (ARM) is supplying this software for use with Cortex-Mx
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
/* memory mapping struct for System Control Block */
typedef struct
{
__I uint32_t CPUID; /*!< CPU ID Base Register */
__IO uint32_t ICSR; /*!< Interrupt Control State Register */
__IO uint32_t VTOR; /*!< Vector Table Offset Register */
__IO uint32_t AIRCR; /*!< Application Interrupt / Reset Control Register */
__IO uint32_t SCR; /*!< System Control Register */
__IO uint32_t CCR; /*!< Configuration Control Register */
__IO uint8_t SHP[12]; /*!< System Handlers Priority Registers (4-7, 8-11, 12-15) */
__IO uint32_t SHCSR; /*!< System Handler Control and State Register */
__IO uint32_t CFSR; /*!< Configurable Fault Status Register */
__IO uint32_t HFSR; /*!< Hard Fault Status Register */
__IO uint32_t DFSR; /*!< Debug Fault Status Register */
__IO uint32_t MMFAR; /*!< Mem Manage Address Register */
__IO uint32_t BFAR; /*!< Bus Fault Address Register */
__IO uint32_t AFSR; /*!< Auxiliary Fault Status Register */
__I uint32_t PFR[2]; /*!< Processor Feature Register */
__I uint32_t DFR; /*!< Debug Feature Register */
__I uint32_t ADR; /*!< Auxiliary Feature Register */
__I uint32_t MMFR[4]; /*!< Memory Model Feature Register */
__I uint32_t ISAR[5]; /*!< ISA Feature Register */
} SCB_Type;
#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */
#define NVIC_AIRCR_VECTKEY (0x5FA << 16) /*!< AIRCR Key for write access */
#define NVIC_SYSRESETREQ 2 /*!< System Reset Request */
/* ################################## Reset function ############################################ */
/**
* @brief Initiate a system reset request.
*
* @param none
* @return none
*
* Initialize a system reset request to reset the MCU
*/
static __INLINE void NVIC_SystemReset(void)
{
SCB->AIRCR = (NVIC_AIRCR_VECTKEY | (SCB->AIRCR & (0x700)) | (1<<NVIC_SYSRESETREQ)); /* Keep priority group unchanged */
__DSB(); /* Ensure completion of memory access */
while(1); /* wait until reset */
}
Ярлыки
_GetPixelIndex
(1)
_SetPixelIndex
(1)
3-phase
(1)
800x480
(1)
АЦП
(1)
генератор
(1)
синхронный усилитель
(2)
структура
(1)
учебный курс
(1)
шаговый двигатель
(1)
ШИМ
(2)
accert
(1)
AD7608
(1)
AD8429
(1)
ADC
(5)
amplifer
(1)
arccos
(1)
arcsin
(1)
arctang
(2)
arctg
(3)
ARM
(2)
arm_sqrt_q15
(2)
assembler
(6)
ASSERT
(1)
atan
(2)
bit
(1)
Bitband
(1)
boot
(3)
bootlloader
(1)
BUTTON
(1)
C
(5)
C#
(1)
CAN
(2)
CC2530
(5)
CMSIS
(4)
command
(1)
Cordic
(1)
Core746I
(1)
CubeMX
(4)
DBGMCU
(2)
debug
(2)
debug.ini
(1)
delegate
(1)
Digital Potentiometers
(1)
DigitalPOT
(1)
Discovery
(1)
DMA
(9)
DMA2D
(1)
DSP
(1)
DSP library
(1)
DWT
(1)
EFM32
(5)
EmWin
(9)
EXTI
(1)
FATFS
(1)
FMC
(2)
FreeRTOS
(2)
gl868-dual cmux
(1)
GPIO
(4)
GUI
(2)
GUIBuilder
(1)
GUIDRV_CompactColor_16
(1)
HAL
(3)
HappyGecko
(1)
Hard Fault
(2)
heap
(1)
I2C
(1)
ID
(1)
ILI9320
(1)
ILI9325
(1)
Initialisation
(1)
InitLTDC
(1)
Instrumentithion
(1)
Interrupt
(4)
ITR
(1)
JTAG
(1)
Keil
(5)
LCDConf
(2)
lock-in
(1)
LTCD
(1)
LTDC
(3)
main
(1)
memory
(1)
MINI_STM32 Revision 01
(1)
nBoot0
(1)
NVIC
(1)
OnePulse
(2)
OSAL
(4)
pack
(1)
phase
(1)
printf
(3)
Pulse
(1)
PWM
(12)
RCC
(2)
RCR
(1)
Register
(1)
RESET
(2)
RS232
(3)
RSS
(1)
RTC
(3)
RTOS-RTX
(1)
RTT
(1)
RTX-RTOS
(1)
SDCard
(1)
SDRAM
(6)
Segger
(2)
SPI
(3)
sqrt
(3)
SSD1298
(1)
SSD1963
(1)
Standart Peripherial Library
(3)
STANDBAY
(1)
startup
(1)
STemWin
(8)
stepper motor
(1)
STlink
(2)
STM32
(17)
STM32429ZI
(1)
STM32Cube
(1)
STM32DBG.IN
(1)
STM32F
(28)
STM32F0
(4)
STM32F1
(13)
STM32F4
(10)
STM32F4 Discovery
(1)
STM32F407ZG
(1)
STM32F429
(2)
STM32F746
(1)
STOP
(1)
string
(1)
struct
(1)
SWD
(1)
SWD JTAG
(1)
Synhronization
(1)
system_stm32f4xx.c
(1)
SystemInit
(1)
SysTick
(1)
task
(4)
telit
(1)
TIM
(27)
typedef
(1)
UART
(1)
USART
(9)
viewer
(2)
WM_PAINT
(1)
Z-stack
(5)
ZigBee
(5)
понедельник, 1 января 2018 г.
CMSIS Library for System Software Reset
SD Card read in FATFS bug (stm32f7xx_hal_sd.c)
I made project for STM32F746 (LTDC, FMC, SDMMC, FATFS, STemWin + FreeRTOS)
I have problem with reading image file (bmp format) from SD card.
My code
int APP_GetData(void * p, const U8 **ppData, unsigned NumBytesReq, U32 Off){
//You must create an pointer on structure
FIL *phFile;
//and then initialize the pointer value is passed to the function APP_GetData
phFile=(FIL*) p;
//And then use this pointer to your function
f_lseek(phFile,Off);
fresult=f_read(phFile,_acBuffer,NumBytesReq,(void*)&bytesread);
*ppData = _acBuffer;
return bytesread;
}
void picture_test(void){
for(image_number = 1; image_number <= 38;image_number++){
sprintf(st_2,"image%03d",image_number);
sprintf(file_name, "%s%s",st_2,st_3 );
fresult=f_open(&MyFile,file_name, FA_READ);
GUI_MULTIBUF_BeginEx(0);
GUI_BMP_DrawEx(APP_GetData, &MyFile,0,0); // Draw image
GUI_MULTIBUF_EndEx(0);
f_close(&MyFile);
HAL_Delay(1000);
}
}
Code is displays several pictures and stops (HardFault)
Problem solved with correct file stm32f7xx_hal_sd.c
from line 637
/* Empty FIFO if there is still any data */
while ((__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL)))
{
*tempbuff = SDMMC_ReadFIFO(hsd->Instance);
// tempbuff++; >>>>>>>>> // tempbuff++; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
{
/* Clear all the static flags */
__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT;
hsd->State= HAL_SD_STATE_READY;
return HAL_ERROR;
}
}
When I comment line
tempbuff++
I have reading from SD card without HardFault.
I have problem with reading image file (bmp format) from SD card.
My code
int APP_GetData(void * p, const U8 **ppData, unsigned NumBytesReq, U32 Off){
//You must create an pointer on structure
FIL *phFile;
//and then initialize the pointer value is passed to the function APP_GetData
phFile=(FIL*) p;
//And then use this pointer to your function
f_lseek(phFile,Off);
fresult=f_read(phFile,_acBuffer,NumBytesReq,(void*)&bytesread);
*ppData = _acBuffer;
return bytesread;
}
void picture_test(void){
for(image_number = 1; image_number <= 38;image_number++){
sprintf(st_2,"image%03d",image_number);
sprintf(file_name, "%s%s",st_2,st_3 );
fresult=f_open(&MyFile,file_name, FA_READ);
GUI_MULTIBUF_BeginEx(0);
GUI_BMP_DrawEx(APP_GetData, &MyFile,0,0); // Draw image
GUI_MULTIBUF_EndEx(0);
f_close(&MyFile);
HAL_Delay(1000);
}
}
Code is displays several pictures and stops (HardFault)
Problem solved with correct file stm32f7xx_hal_sd.c
from line 637
/* Empty FIFO if there is still any data */
while ((__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL)))
{
*tempbuff = SDMMC_ReadFIFO(hsd->Instance);
// tempbuff++; >>>>>>>>> // tempbuff++; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
{
/* Clear all the static flags */
__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT;
hsd->State= HAL_SD_STATE_READY;
return HAL_ERROR;
}
}
When I comment line
tempbuff++
I have reading from SD card without HardFault.
вторник, 26 декабря 2017 г.
EmWin CreateDialogBox CreateWindow
Creates a dialog box.
WM_HWIN GUI_CreateDialogBox(const GUI_WIDGET_CREATE_INFO * paWidget,
int NumWidgets,
WM_CALLBACK * cb,
WM_HWIN hParent,
int x0,
int y0);
paWidget Pointer to resource table defining the widgets to be included in the dialog.
NumWidgets Total number of widgets included in the dialog.
cb Pointer to an application-specific callback function (dialog procedure).
hParent Handle of parent window (0 = no parent window).
x0 X-position of the dialog relative to parent window.
y0 Y-position of the dialog relative to parent window.
Creates a window of a specified size at a specified location.
WM_HWIN WM_CreateWindow(
int x0,
int y0,
int width,
int height,
U32 Style,
WM_CALLBACK * cb,
int NumExtraBytes);
x0 Upper left X-position in desktop coordinates.
y0 Upper left Y-position in desktop coordinates.
width X-size of window.
height Y-size of window.
Style Window create flags, listed below.
cb Pointer to callback routine, or NULL if no callback used.
NumExtraBytes Number of extra bytes to be allocated, normally 0.
WM_HWIN GUI_CreateDialogBox(const GUI_WIDGET_CREATE_INFO * paWidget,
int NumWidgets,
WM_CALLBACK * cb,
WM_HWIN hParent,
int x0,
int y0);
paWidget Pointer to resource table defining the widgets to be included in the dialog.
NumWidgets Total number of widgets included in the dialog.
cb Pointer to an application-specific callback function (dialog procedure).
hParent Handle of parent window (0 = no parent window).
x0 X-position of the dialog relative to parent window.
y0 Y-position of the dialog relative to parent window.
Creates a window of a specified size at a specified location.
WM_HWIN WM_CreateWindow(
int x0,
int y0,
int width,
int height,
U32 Style,
WM_CALLBACK * cb,
int NumExtraBytes);
x0 Upper left X-position in desktop coordinates.
y0 Upper left Y-position in desktop coordinates.
width X-size of window.
height Y-size of window.
Style Window create flags, listed below.
cb Pointer to callback routine, or NULL if no callback used.
NumExtraBytes Number of extra bytes to be allocated, normally 0.
среда, 27 сентября 2017 г.
EmWin - loading from external SD card dta file
BitmapConverter are .dta files. Those are almost the same as the c-files, just in a binary form.
Take a look at functions like GUI_DrawStreamedBitmapExAuto() and at chapter 8.1.5 'Drawing streamed bitmaps'.
To use them you have to set a get data function which reads the data from the .dta file.
Besides of the .dta files you can also draw BMP, JPEG, or PNG files.
But those have the disadvantage that they need to be decoded which is slower than using the .dta files.
Here is a short example on how to draw a .dta file.
This is for windows filesystem but it should be easy to adapt for any other filesystem. Of course you need a .dta file and set the proper path in MainTask.
#include <windows.h> #include "GUI.h" /********************************************************************* * * _GetData */ static int _GetData(void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off) { HANDLE * phFile; DWORD NumBytesRead; U8 * pData; pData = (U8 *)*ppData; phFile = (HANDLE *)p; // // Set file pointer to the required position // SetFilePointer(*phFile, Off, 0, FILE_BEGIN); // // Read data into buffer // ReadFile(*phFile, pData, NumBytesReq, &NumBytesRead, NULL); // // Return number of available bytes // return NumBytesRead; } /********************************************************************* * * Public code * ********************************************************************** */ /********************************************************************* * * MainTask */ void MainTask(void) { HANDLE hFile; char acPath[] = "Path to .dta file"; GUI_Init(); hFile = CreateFile(acPath, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); GUI_DrawStreamedBitmapExAuto(_GetData, (void *)&hFile, 0, 0); CloseHandle(hFile); while (1) { GUI_Delay(100); } }
четверг, 10 августа 2017 г.
воскресенье, 6 августа 2017 г.
STM32F746 Memory Region
MPU_Region_InitTypeDef MPU_InitStruct_SDRAM;
MPU_Region_InitTypeDef MPU_InitStruct_FPGAKBD;
В 746-м, сразу после настройки FMC, возможен только доступ по четным (выровненным на 4 байта адресам). Для доступа к нечетным адресам надо еще настраивать MPU на эти области адресов. Иначе проц выпадает в Hard Fault exception handler.
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU attributes as WT for SDRAM */
MPU_InitStruct_SDRAM.Number = MPU_REGION_NUMBER0;
MPU_InitStruct_SDRAM.BaseAddress = 0xD0000000;
MPU_InitStruct_SDRAM.Size = MPU_REGION_SIZE_8MB;
MPU_InitStruct_SDRAM.Enable = MPU_REGION_ENABLE;
MPU_InitStruct_SDRAM.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct_SDRAM.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct_SDRAM.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct_SDRAM.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct_SDRAM.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct_SDRAM.SubRegionDisable = 0x00;
MPU_InitStruct_SDRAM.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct_SDRAM);
MPU_InitStruct_FPGAKBD.Number = MPU_REGION_NUMBER1;
MPU_InitStruct_FPGAKBD.BaseAddress = 0x60000000;
MPU_InitStruct_FPGAKBD.Size = MPU_REGION_SIZE_512MB;
MPU_InitStruct_FPGAKBD.Enable = MPU_REGION_ENABLE;
MPU_InitStruct_FPGAKBD.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct_FPGAKBD.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct_FPGAKBD.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct_FPGAKBD.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct_FPGAKBD.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct_FPGAKBD.SubRegionDisable = 0x00;
MPU_InitStruct_FPGAKBD.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct_FPGAKBD);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
MPU_Region_InitTypeDef MPU_InitStruct_FPGAKBD;
В 746-м, сразу после настройки FMC, возможен только доступ по четным (выровненным на 4 байта адресам). Для доступа к нечетным адресам надо еще настраивать MPU на эти области адресов. Иначе проц выпадает в Hard Fault exception handler.
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU attributes as WT for SDRAM */
MPU_InitStruct_SDRAM.Number = MPU_REGION_NUMBER0;
MPU_InitStruct_SDRAM.BaseAddress = 0xD0000000;
MPU_InitStruct_SDRAM.Size = MPU_REGION_SIZE_8MB;
MPU_InitStruct_SDRAM.Enable = MPU_REGION_ENABLE;
MPU_InitStruct_SDRAM.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct_SDRAM.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct_SDRAM.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct_SDRAM.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct_SDRAM.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct_SDRAM.SubRegionDisable = 0x00;
MPU_InitStruct_SDRAM.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct_SDRAM);
MPU_InitStruct_FPGAKBD.Number = MPU_REGION_NUMBER1;
MPU_InitStruct_FPGAKBD.BaseAddress = 0x60000000;
MPU_InitStruct_FPGAKBD.Size = MPU_REGION_SIZE_512MB;
MPU_InitStruct_FPGAKBD.Enable = MPU_REGION_ENABLE;
MPU_InitStruct_FPGAKBD.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct_FPGAKBD.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct_FPGAKBD.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct_FPGAKBD.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct_FPGAKBD.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct_FPGAKBD.SubRegionDisable = 0x00;
MPU_InitStruct_FPGAKBD.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct_FPGAKBD);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
Fault Handler processing
#define USART_FLAG_TC ((uint16_t)0x0040)
static __INLINE void ITM_SendChar_My (uint32_t ch)
{
while( (USART1->ISR & USART_FLAG_TC ) == 0 )
{
;
}
USART1->TDR = (ch & (uint16_t)0x01FF);
}
void printErrorMsg(const char * errMsg)
{
while( *errMsg != 0 )
{
ITM_SendChar_My(*errMsg);
++errMsg;
}
}
static __INLINE void ITM_SendChar_My (uint32_t ch)
{
while( (USART1->ISR & USART_FLAG_TC ) == 0 )
{
;
}
USART1->TDR = (ch & (uint16_t)0x01FF);
}
void printErrorMsg(const char * errMsg)
{
while( *errMsg != 0 )
{
ITM_SendChar_My(*errMsg);
++errMsg;
}
}
Restarting UART DMA
Restarting UART DMA using HAL
HAL_DMA_Abort
HAL_UART_DMAStop
and recalling the DMA initialisation routine but it still doesn't restart correctly
add
__HAL_USART_CLEAR_OREFLAG(&huart1);
====================================================
DMA_Cmd(DMA1_Channel1, DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel1, 3000);
DMA_Cmd(DMA1_Channel1, ENABLE);
1. выключить канал dma
2. записать в CNDTR размер буфера
3. включить dma
при отладке с остановами работаеттолько такой код:
1a. выключить uart
1. выключить канал dma
2. записать в CNDTR размер буфера
2.a записать CCR то что писалось при инициализации
3. включить dma
3a. включить uart
============================================================
void DMA1_Channel4_IRQHandler(void)
{
DMA1->IFCR |= DMA_ISR_TCIF4;//очистить флаг окончания обмена.
}
HAL_DMA_Abort
HAL_UART_DMAStop
and recalling the DMA initialisation routine but it still doesn't restart correctly
add
__HAL_USART_CLEAR_OREFLAG(&huart1);
====================================================
DMA_Cmd(DMA1_Channel1, DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel1, 3000);
DMA_Cmd(DMA1_Channel1, ENABLE);
1. выключить канал dma
2. записать в CNDTR размер буфера
3. включить dma
при отладке с остановами работаеттолько такой код:
1a. выключить uart
1. выключить канал dma
2. записать в CNDTR размер буфера
2.a записать CCR то что писалось при инициализации
3. включить dma
3a. включить uart
============================================================
void DMA1_Channel4_IRQHandler(void)
{
DMA1->IFCR |= DMA_ISR_TCIF4;//очистить флаг окончания обмена.
}
========================================================
To start another DMA transaction you should program a transaction length. It can be programmed only when a DMA channel disabled. So in your case code might looks like this:
void DMA1_Channel5_IRQHandler(void) {
DMA_ClearITPendingBit(DMA1_IT_TC5);
DMA_Cmd(DMA1_Channel5, DISABLE);
DMA1_Channel5->CNDTR = UART_PACKET_SIZE; // <--- transaction length
DMA_Cmd(DMA1_Channel5, ENABLE);
}
Or you can use your function uart_receive_dma(), but you should disable a DMA channel prior to calling it.
void DMA1_Channel5_IRQHandler(void) {
DMA_ClearITPendingBit(DMA1_IT_TC5);
DMA_Cmd(DMA1_Channel5, DISABLE);
uart_receive_dma();
}
Second variant will do same thing as first, but will take much more time.
пятница, 4 августа 2017 г.
EmWin skins for buttons.
#include "DIALOG.h"
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#define ID_WINDOW_0 (GUI_ID_USER + 0x00)
#define ID_BUTTON_0 (GUI_ID_USER + 0x01)
#define ID_BUTTON_1 (GUI_ID_USER + 0x02)
#define ID_BUTTON_2 (GUI_ID_USER + 0x03)
#define ID_BUTTON_3 (GUI_ID_USER + 0x04)
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
/*********************************************************************
*
* _aDialogCreate
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
{ WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 320, 240, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 20, 10, 80, 20, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_1, 20, 40, 80, 20, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_2, 20, 70, 80, 20, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_3, 20, 100, 80, 20, 0, 0x0, 0 },
};
static BUTTON_SKINFLEX_PROPS _aProps[] = {
// BUTTON_SKINFLEX_PI_PRESSED
{
{GUI_RED, GUI_RED, GUI_DARKRED},
{GUI_LIGHTRED, GUI_RED },
{GUI_RED, GUI_DARKRED },
3
},
// BUTTON_SKINFLEX_PI_FOCUSSED
{
{GUI_DARKRED, GUI_RED, GUI_DARKGRAY},
{GUI_LIGHTGRAY, GUI_GRAY },
{GUI_GRAY, GUI_DARKGRAY },
3
},
// BUTTON_SKINFLEX_PI_ENABLED
{
{GUI_DARKRED, GUI_GRAY, GUI_DARKGRAY},
{GUI_LIGHTGRAY, GUI_GRAY },
{GUI_GRAY, GUI_DARKGRAY },
3
},
// BUTTON_SKINFLEX_PI_DISABLED
{
{0, 0, 0},
{0, 0 },
{0, 0 },
3
},
};
/*********************************************************************
*
* Static code
*
**********************************************************************
*/
/*********************************************************************
*
* _CustomSkin
*/
static int _CustomSkin(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo) {
int Id;
GUI_POINT aPoints[3];
GUI_COLOR Color;
BUTTON_SKINFLEX_PROPS aPropsOld[4];
int i;
switch (pDrawItemInfo->Cmd) {
case WIDGET_ITEM_DRAW_BACKGROUND:
Id = WM_GetId(pDrawItemInfo->hWin);
switch (Id) {
case ID_BUTTON_0:
//
// Draw an elliptic button
//
if (BUTTON_IsPressed(pDrawItemInfo->hWin)) {
Color = GUI_YELLOW;
} else {
Color = GUI_RED;
}
GUI_SetColor(Color);
GUI_FillEllipse(pDrawItemInfo->x1 / 2, pDrawItemInfo->y1 / 2, pDrawItemInfo->x1 / 2 - 1, pDrawItemInfo->y1 / 2 - 1);
break;
case ID_BUTTON_1:
//
// Draw a triangle button
//
aPoints[0].x = pDrawItemInfo->x1 / 2;
aPoints[0].y = pDrawItemInfo->y0;
aPoints[1].x = pDrawItemInfo->x1;
aPoints[1].y = pDrawItemInfo->y1;
aPoints[2].x = pDrawItemInfo->x0;
aPoints[2].y = pDrawItemInfo->y1;
if (BUTTON_IsPressed(pDrawItemInfo->hWin)) {
Color = GUI_GREEN;
} else {
Color = GUI_CYAN;
}
GUI_SetColor(Color);
GUI_FillPolygon(aPoints, GUI_COUNTOF(aPoints), pDrawItemInfo->x0, pDrawItemInfo->y0);
break;
case ID_BUTTON_2:
//
// Draw a standard button with different colors
//
for (i = 0; i < 4; i++) {
BUTTON_GetSkinFlexProps(&aPropsOld[i], i); // Get default properties
BUTTON_SetSkinFlexProps(&_aProps[i], i); // Set new properties
}
BUTTON_DrawSkinFlex(pDrawItemInfo); // Draw button with new properties
for (i = 0; i < 4; i++) {
BUTTON_SetSkinFlexProps(&aPropsOld[i], i); // Restore old properties to avoid other buttons will be drawn with this properties
}
break;
case ID_BUTTON_3:
BUTTON_DrawSkinFlex(pDrawItemInfo);
break;
}
return 0;
default:
return BUTTON_DrawSkinFlex(pDrawItemInfo);
}
}
/*********************************************************************
*
* _cbDialog
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
WM_HWIN hItem;
int NCode;
int Id;
switch (pMsg->MsgId) {
case WM_INIT_DIALOG:
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
BUTTON_SetSkin(hItem, _CustomSkin);
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
BUTTON_SetSkin(hItem, _CustomSkin);
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2);
BUTTON_SetSkin(hItem, _CustomSkin);
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_3);
BUTTON_SetSkin(hItem, _CustomSkin);
break;
default:
WM_DefaultProc(pMsg);
break;
}
}
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
WM_HWIN CreateWindow(void);
WM_HWIN CreateWindow(void) {
WM_HWIN hWin;
hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
return hWin;
}
/*********************************************************************
*
* MainTask
*/
//////////void MainTask(void) {
////////// //
////////// // Set flag for automatic use of memory devices. Calling before GUI_Init() makes sure the desktop window uses them, too.
////////// //
////////// WM_SetCreateFlags(WM_CF_MEMDEV);
////////// //
////////// // Initialize GUI
////////// //
////////// GUI_Init();
////////// GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
////////// while (1) {
////////// GUI_Delay(100);
////////// }
//////////}
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#define ID_WINDOW_0 (GUI_ID_USER + 0x00)
#define ID_BUTTON_0 (GUI_ID_USER + 0x01)
#define ID_BUTTON_1 (GUI_ID_USER + 0x02)
#define ID_BUTTON_2 (GUI_ID_USER + 0x03)
#define ID_BUTTON_3 (GUI_ID_USER + 0x04)
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
/*********************************************************************
*
* _aDialogCreate
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
{ WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 320, 240, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 20, 10, 80, 20, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_1, 20, 40, 80, 20, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_2, 20, 70, 80, 20, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_3, 20, 100, 80, 20, 0, 0x0, 0 },
};
static BUTTON_SKINFLEX_PROPS _aProps[] = {
// BUTTON_SKINFLEX_PI_PRESSED
{
{GUI_RED, GUI_RED, GUI_DARKRED},
{GUI_LIGHTRED, GUI_RED },
{GUI_RED, GUI_DARKRED },
3
},
// BUTTON_SKINFLEX_PI_FOCUSSED
{
{GUI_DARKRED, GUI_RED, GUI_DARKGRAY},
{GUI_LIGHTGRAY, GUI_GRAY },
{GUI_GRAY, GUI_DARKGRAY },
3
},
// BUTTON_SKINFLEX_PI_ENABLED
{
{GUI_DARKRED, GUI_GRAY, GUI_DARKGRAY},
{GUI_LIGHTGRAY, GUI_GRAY },
{GUI_GRAY, GUI_DARKGRAY },
3
},
// BUTTON_SKINFLEX_PI_DISABLED
{
{0, 0, 0},
{0, 0 },
{0, 0 },
3
},
};
/*********************************************************************
*
* Static code
*
**********************************************************************
*/
/*********************************************************************
*
* _CustomSkin
*/
static int _CustomSkin(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo) {
int Id;
GUI_POINT aPoints[3];
GUI_COLOR Color;
BUTTON_SKINFLEX_PROPS aPropsOld[4];
int i;
switch (pDrawItemInfo->Cmd) {
case WIDGET_ITEM_DRAW_BACKGROUND:
Id = WM_GetId(pDrawItemInfo->hWin);
switch (Id) {
case ID_BUTTON_0:
//
// Draw an elliptic button
//
if (BUTTON_IsPressed(pDrawItemInfo->hWin)) {
Color = GUI_YELLOW;
} else {
Color = GUI_RED;
}
GUI_SetColor(Color);
GUI_FillEllipse(pDrawItemInfo->x1 / 2, pDrawItemInfo->y1 / 2, pDrawItemInfo->x1 / 2 - 1, pDrawItemInfo->y1 / 2 - 1);
break;
case ID_BUTTON_1:
//
// Draw a triangle button
//
aPoints[0].x = pDrawItemInfo->x1 / 2;
aPoints[0].y = pDrawItemInfo->y0;
aPoints[1].x = pDrawItemInfo->x1;
aPoints[1].y = pDrawItemInfo->y1;
aPoints[2].x = pDrawItemInfo->x0;
aPoints[2].y = pDrawItemInfo->y1;
if (BUTTON_IsPressed(pDrawItemInfo->hWin)) {
Color = GUI_GREEN;
} else {
Color = GUI_CYAN;
}
GUI_SetColor(Color);
GUI_FillPolygon(aPoints, GUI_COUNTOF(aPoints), pDrawItemInfo->x0, pDrawItemInfo->y0);
break;
case ID_BUTTON_2:
//
// Draw a standard button with different colors
//
for (i = 0; i < 4; i++) {
BUTTON_GetSkinFlexProps(&aPropsOld[i], i); // Get default properties
BUTTON_SetSkinFlexProps(&_aProps[i], i); // Set new properties
}
BUTTON_DrawSkinFlex(pDrawItemInfo); // Draw button with new properties
for (i = 0; i < 4; i++) {
BUTTON_SetSkinFlexProps(&aPropsOld[i], i); // Restore old properties to avoid other buttons will be drawn with this properties
}
break;
case ID_BUTTON_3:
BUTTON_DrawSkinFlex(pDrawItemInfo);
break;
}
return 0;
default:
return BUTTON_DrawSkinFlex(pDrawItemInfo);
}
}
/*********************************************************************
*
* _cbDialog
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
WM_HWIN hItem;
int NCode;
int Id;
switch (pMsg->MsgId) {
case WM_INIT_DIALOG:
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
BUTTON_SetSkin(hItem, _CustomSkin);
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
BUTTON_SetSkin(hItem, _CustomSkin);
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2);
BUTTON_SetSkin(hItem, _CustomSkin);
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_3);
BUTTON_SetSkin(hItem, _CustomSkin);
break;
default:
WM_DefaultProc(pMsg);
break;
}
}
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
WM_HWIN CreateWindow(void);
WM_HWIN CreateWindow(void) {
WM_HWIN hWin;
hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
return hWin;
}
/*********************************************************************
*
* MainTask
*/
//////////void MainTask(void) {
////////// //
////////// // Set flag for automatic use of memory devices. Calling before GUI_Init() makes sure the desktop window uses them, too.
////////// //
////////// WM_SetCreateFlags(WM_CF_MEMDEV);
////////// //
////////// // Initialize GUI
////////// //
////////// GUI_Init();
////////// GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
////////// while (1) {
////////// GUI_Delay(100);
////////// }
//////////}
четверг, 3 августа 2017 г.
Add CMSIS-RTOS RTX & CubeMX adapt generated files
This section explains how to add the CMSIS-RTOS RTX real-time operating system.
Setup in STM32CubeMX
In STM32CubeMX ensure that the System Tick Interrupt is set to the lowest priority (which is the highest number).
Configuration tab
- Under System open NVIC Configuration.
- Click on System tick timer and set Preemption Priority to 15 (highest possible value).
- Click OK to close the NVIC Configuration dialog.
Setup in MDK
In MDK, the steps to add the CMSIS-RTOS RTX real-time operating system to a project that is configured with STM32CubeMX are:
Step 1: Add CMSIS-RTOS RTX
- Open the Manage Run-Time Environment window and add CMSIS:RTOS (API):Keil RTX.
Step 2: Configure CMSIS-RTOS RTX parameters
- Open the configuration file RTX_Conf_CM.c from the project window, component group CMSIS.
- Optionally you may change to the Configuration Wizard tab.
- Change the following settings:
- Main Thread stack size [bytes] 1024
- RTOS Kernel Timer input clock frequency [Hz] set to core clock frequency
- Save the file.
Step 3: Add code for CMSIS-RTOS RTX in 'main.c'
- Open the source file main.c from the project window, source group STM32CubeMX:Common Sources and add code lines in the sections USER CODE BEGIN / USER CODE END as shown below:
:
/* USER CODE BEGIN Includes */
#include "cmsis_os.h" // ARM::CMSIS:RTOS:Keil RTX
/* USER CODE END Includes */
:
/* USER CODE BEGIN 0 */
extern uint32_t os_time;
uint32_t HAL_GetTick(void) { // Add HAL_GetTick function for STM32Cube HAL
return os_time;
}
/* USER CODE END 0 */
:
int main(void)
{
:
/* USER CODE BEGIN 1 */
osKernelInitialize (); // Initialize RTOS Kernel for setup
/* USER CODE END 1 */
:
/* USER CODE BEGIN 2 */
osKernelStart (); // Begin thread switching
/* USER CODE END 2 */
:
Step 4: Remove SysTick_Handler in stm32f7xx_it.c
- STM32CubeMX generates a SysTick_Handler that is in-compatible with CMSIS-RTOS RTX. Remove the code for the SysTick_Handler in the source file stm32f7xx_it.c as shown below.
#if 0
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
#endif
Step 5: Build Project in MDK
- Use Project - Build Target to generate the application code.
The source file generated by STM32CubeMX can be accessed in the MDK project window, source group STM32CubeMX:Common Sources. These file require the following modifications.
Changes to 'stm32fxxx_it.c'
CMSIS-Driver and CMSIS-RTOS RTX implement their own interrupt handlers.
- For using CMSIS-RTOS RTX remove the code of the SysTick_Handler.
- For using CMSIS-Driver remove the code of the related Interruption Handler.
- Note
- STM32CubeMX re-generates this file and it is required to remove the interrupt handlers after using Generate Code.
Changes to 'main.c'
- CMSIS-Driver initialize peripherals using dedicated functions that are called by middleware. Initialization code in 'main.c' for the related peripherals is therefore not required and may be removed.
- CMSIS-RTOS RTX requires initialization code. Refer to Add CMSIS-RTOS RTX for detailed information.
Подписаться на:
Сообщения (Atom)

