Ярлыки

_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)

вторник, 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.

среда, 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);
  }
}

воскресенье, 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);

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;
 }
}

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;//очистить флаг окончания обмена.
}

========================================================

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);
//////////  }
//////////}

четверг, 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.

rte_bsp_rtx.png

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.

воскресенье, 30 июля 2017 г.

GUIconf with external SDRAM

#define GUI_NUMBYTES (1024) * 120 ---> what about this ??


#define GUI_BUFFER_IN_EXT_RAM 1
#define GUI_BUFFER_ADDRESS 0xD0600000
#define OS_SUPPORT 1



void GUI_X_Config(void) {

//
// 32 bit aligned memory area
//
#ifdef GUI_BUFFER_IN_EXT_RAM
static U32 aMemory[GUI_NUMBYTES / 4]__attribute__((at(GUI_BUFFER_ADDRESS)));
#else
static U32 aMemory[GUI_NUMBYTES / 4];
#endif
//
// Assign memory to emWin
//
GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES);
//
// Set default font
//
GUI_SetDefaultFont(GUI_FONT_6X8);
}

STM3F429 SDRAM Init

///Install SDRAM stm32f439
FMC_Bank5_6 -> SDCR[0] = FMC_SDCR1_NC_9bits
|FMC_SDCR1_NR_13bits
|FMC_SDCR1_MWID_16bits
|FMC_SDCR1_NB_4banks
|FMC_SDCR1_CAS_2cycle
//|FMC_SDCR1_SDCLK_3x
|FMC_SDCR1_SDCLK_2x
|FMC_SDCR2_RBURST
|FMC_SDCR1_WP
|FMC_SDCR1_RPIPE_1delay; //FMC_SDCR1_RPIPE_1delay FMC_SDCR1_RPIPE_3delay

FMC_Bank5_6->SDTR[0] = (0x00000001) /// TMRD время между записью в MODE-REGISTER и ACTIVATE/1 /2
|(0x00000005 << 4) /// TXSR время между SELF-REFRESHING и ACTIVATE (exit self-refresh mode)/5 /7
|(0x00000002 << 8) /// TRAS минимальное время между SELF-REFRESH/2 /4
|(0x00000006 << 12) /// TRC время между двумя командами REFRESH/5 /7
|(0x00000003 << 16) /// TWR задержка между командой WRITE и вызовом PRECHARGE/1 /2
|(0x00000001 << 20) /// TRP время между командой PRECHARGE и любой другой командой/1 /1
|(0x00000002 << 24); /// TRCD время между подачей команды ACTIVATE и появлением данных на шинеС/1 /2
///TWR >= TRAS - TRCD and TWR >= TRC - TRCD - TRP
FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB1 | FMC_SDCMR_MODE_Config_Enable;
tmp = FMC_Bank5_6->SDSR & 0x00000020;
timeout = 0xFFFF;
while((tmp != 0) && (timeout-- > 0))
{
tmp = FMC_Bank5_6->SDSR & 0x00000020;
}

delay(10000);
/// PALL command
FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB1 | FMC_SDCMR_MODE_PALL;
timeout = 0xFFFF; tmp = 10;
while((tmp != 0) && (timeout-- > 0))
{
tmp = FMC_Bank5_6->SDSR & 0x00000020;
}
/// Auto refresh command
FMC_Bank5_6->SDCMR = (0x00000003 << 5) | FMC_SDCMR_CTB1 | FMC_SDCMR_MODE_Self_refresh;
/// Количество рефлеш минимум 2
timeout = 0xFFFF; tmp = 10;
while((tmp != 0) && (timeout-- > 0))
{
tmp = FMC_Bank5_6->SDSR & 0x00000020;
}
// MRD register program
tmp = (((((HSE_gz / (((RCC->PLLCFGR)<<26)>>26))*(((RCC->PLLCFGR)<<17)>>23))/(((((RCC->PLLCFGR)<<14)>>30)<<1)+2))/2000)*64)/8192;
FMC_Bank5_6->SDCMR = (tmp << 9) | FMC_SDCMR_CTB1 | FMC_SDCMR_MODE_Load_Mode;
/// 64mc/(размер блока Row Addresses(8192)) * (тактовая частота чипа)
timeout = 0xFFFF; tmp = 10;
while((tmp != 0) && (timeout-- > 0))
{
tmp = FMC_Bank5_6->SDSR & 0x00000020;
}
tmp = (((((((HSE_gz / (((RCC->PLLCFGR)<<26)>>26))*(((RCC->PLLCFGR)<<17)>>23))/(((((RCC->PLLCFGR)<<14)>>30)<<1)+2))/2000)*64)/8192)<<1) | FMC_Bank5_6->SDRTR;
FMC_Bank5_6->SDRTR = (tmp | (0x000002C5<<1)) | 1<<14; // время регена + вкл регена
/// Refresh rate = (COUNT) * SDRAM clock frequency
/// SDRAM refresh period = 64 mc
/// COUNT = (SDRAM refresh period / Number of rows )
/// Refresh rate = 0.064 / (8192rows + 4) ) * 84000000 , ~ 656 ( 0x290 )

FMC_Bank5_6->SDCR[0] &= (~FMC_SDCR1_WP);// снятие защиты от записи
// timeout =0;
for(tmp = 0xc0000000; tmp < 0xC1FFFFFC; tmp += 4) ///32Mb 0.873 ms
{
*((volatile uint32_t *)tmp) = 0x00000000;// timeout;
}



MEMORY
{
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 192K
SRAM (rwx) : ORIGIN = 0xD0000000, LENGTH = 64K
CCRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K
SDRAM (rwx) : ORIGIN = 0xC0000000, LENGTH = 16384K
BKRAM (rw) : ORIGIN = 0x40024000, LENGTH = 4K
}
linker
--------------
/* размещение констант в SDRAM */
_sicsdram = LOADADDR(.csdram);
.csdram :
{
. = ALIGN(4);
_scsdram = .; /* глобальный символ начала SDRAM */
*(.csdram)
*(.csdram*)
. = ALIGN(4);
_ecsdram = .; /* глобальный символ конца SDRAM */
} > SDRAM AT> FLASH

---------------
*.s файл

bl SystemInit

ldr r0, =_scsdram
ldr r1, =_sicsdram
ldr r2, =_ecsdram
LoopCopySdram:
cmp r0, r2
ittt ne
ldrne r3, [r1], #4
strne r3, [r0], #4
bne LoopCopySdram

bl main

---------

макрос
#define SDram __attribute__((section(".csdram")))
----------
глобальные переменные
SDram const uint16_t Font[размер] ={дата};

суббота, 29 июля 2017 г.

LCDconf.c for STM32746G-Discovery problem

Original
#define COLOR_CONVERSION_0 GUICC_M8888I
#define DISPLAY_DRIVER_0   GUIDRV_LIN_32

Correct
#define COLOR_CONVERSION_0 GUICC_M888
#define DISPLAY_DRIVER_0   GUIDRV_LIN_24

Original
static inline U32 LCD_LL_GetPixelformat(U32 LayerIndex)
{
  if (LayerIndex == 0)
  {
    return LTDC_PIXEL_FORMAT_ARGB8888;
  } 
  else
  {
    return LTDC_PIXEL_FORMAT_ARGB1555;
  } 
}


Correct
static uint32_t LCD_LL_GetPixelformat(uint32_t LayerIndex)
{
  const LCD_API_COLOR_CONV * pColorConvAPI;

  if (LayerIndex >= GUI_NUM_LAYERS) 
  {
    return 0;
  }
  pColorConvAPI = layer_prop[LayerIndex].pColorConvAPI;
  
  if (pColorConvAPI == GUICC_M8888I) 
  {
    return LTDC_PIXEL_FORMAT_ARGB8888;
  } 
  else if (pColorConvAPI == GUICC_M888) 
  {
    return LTDC_PIXEL_FORMAT_RGB888;
  } 
  else if (pColorConvAPI == GUICC_M565) 
  {
    return LTDC_PIXEL_FORMAT_RGB565;
  } 
  else if (pColorConvAPI == GUICC_M1555I) 
  {
    return LTDC_PIXEL_FORMAT_ARGB1555;
  } 
  else if (pColorConvAPI == GUICC_M4444I) 
  {
    return LTDC_PIXEL_FORMAT_ARGB4444;
  } 
  else if (pColorConvAPI == GUICC_8666) 
  {
    return LTDC_PIXEL_FORMAT_L8;
  } 
  else if (pColorConvAPI == GUICC_1616I) 
  {
    return LTDC_PIXEL_FORMAT_AL44;
  } 
  else if (pColorConvAPI == GUICC_88666I) 
  {
    return LTDC_PIXEL_FORMAT_AL88;
  }
  while (1);
}







воскресенье, 23 июля 2017 г.

Core746I SDRAM init remap

                                                  CubeMX Default                      Core746I

FMC_SDNWE                                 PCO                                       PH5

( Press CTRL & click mouse in CubeMX for setting remap)

REM this command in file dma2d.c in function void MX_DMA2D_Init(void)

  hdma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA;
  hdma2d.LayerCfg[1].RedBlueSwap = DMA2D_RB_REGULAR;

It is bug of GubeMX.

пятница, 21 июля 2017 г.

LTDC config for STM32F429ZI in CubeMX

                          Default LTDC config               LTDCconfig for board
                           for CubeMX config                STM32F429 Discovery

LTDC_R7                    PE15                                            PG6
LTDC_R6                    PB1                                              PB1
LTDC_R5                    PA12                                            PA12
LTDC_R4                    PA11                                            PA11
LTDC_R3                    PB0                                              PB0
LTDC_R2                    PC10                                            PC10

LTDC_G7                    PD3                                             PD3
LTDC_G6                    PC7                                             PC7
LTDC_G5                    PB11                                           PB11
LTDC_G4                    PB10                                           PB10
LTDC_G3                    PE11                                           PG10
LTDC_G2                    PA6                                             PA6

LTDC_B7                    PB9                                             PB9
LTDC_B6                    PB8                                             PB8
LTDC_B5                    PA3                                             PA3
LTDC_B4                    PE12                                           PG12
LTDC_B3                    PD10                                           PG11
LTDC_B2                    PD6                                             PD6

LTDC_CLK                  PE14                                           PG7
LTCD_VSYNC              PA4                                             PA4
LTDC_HSYNC              PC6                                             PC6
LTDC_DE                    PF10                                           PF10




The required size for your framebuffer can be calculated as follows:

xSize * ySize * BytesPerPixel * NumberOfBuffers
= 320 * 240 * 2 * 1
= 153600 Bytes

четверг, 15 июня 2017 г.

SDRAM + LTDC + DMA2D init CMSIS

#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)

// *** Биты контроллера FMC ***
// Программирование контроллера

#define FMC_ColumnBits_Number_8b ((uint32_t)0x00000000)
#define FMC_ColumnBits_Number_9b ((uint32_t)0x00000001)
#define FMC_ColumnBits_Number_10b ((uint32_t)0x00000002)
#define FMC_ColumnBits_Number_11b ((uint32_t)0x00000003)

#define FMC_RowBits_Number_11b ((uint32_t)0x00000000)
#define FMC_RowBits_Number_12b ((uint32_t)0x00000004)
#define FMC_RowBits_Number_13b ((uint32_t)0x00000008)

#define FMC_NORSRAM_MemoryDataWidth_8b ((uint32_t)0x00000000)
#define FMC_NORSRAM_MemoryDataWidth_16b ((uint32_t)0x00000010)
#define FMC_NORSRAM_MemoryDataWidth_32b ((uint32_t)0x00000020)

#define FMC_InternalBank_Number_2 ((uint32_t)0x00000000)
#define FMC_InternalBank_Number_4 ((uint32_t)0x00000040)

#define FMC_CAS_Latency_1 ((uint32_t)0x00000080)
#define FMC_CAS_Latency_2 ((uint32_t)0x00000100)
#define FMC_CAS_Latency_3 ((uint32_t)0x00000180)

#define FMC_Write_Protection_Disable ((uint32_t)0x00000000)
#define FMC_Write_Protection_Enable ((uint32_t)0x00000200)

#define FMC_SDClock_Disable ((uint32_t)0x00000000)
#define FMC_SDClock_Period_2 ((uint32_t)0x00000800)
#define FMC_SDClock_Period_3 ((uint32_t)0x00000C00)

#define FMC_Read_Burst_Disable ((uint32_t)0x00000000)
#define FMC_Read_Burst_Enable ((uint32_t)0x00001000)

#define FMC_ReadPipe_Delay_0 ((uint32_t)0x00000000)
#define FMC_ReadPipe_Delay_1 ((uint32_t)0x00002000)
#define FMC_ReadPipe_Delay_2 ((uint32_t)0x00004000)


// Комманды контроллера
#define FMC_Command_Mode_normal ((uint32_t)0x00000000)
#define FMC_Command_Mode_CLK_Enabled ((uint32_t)0x00000001)
#define FMC_Command_Mode_PALL ((uint32_t)0x00000002)
#define FMC_Command_Mode_AutoRefresh ((uint32_t)0x00000003)
#define FMC_Command_Mode_LoadMode ((uint32_t)0x00000004)
#define FMC_Command_Mode_Selfrefresh ((uint32_t)0x00000005)
#define FMC_Command_Mode_PowerDown ((uint32_t)0x00000006)

#define FMC_Command_Target_bank2 ((uint32_t)0x00000008)
#define FMC_Command_Target_bank1 ((uint32_t)0x00000010)
#define FMC_Command_Target_bank1_2 ((uint32_t)0x00000018)

// управление памятью
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAM ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)



// Инициализация ОЗУ на плате.
void draminit(void)
{
uint32_t tmp = 0;
uint32_t timeout = SDRAM_TIMEOUT;


// Инициализация пинов памяти
PINSDRAM_INIT;
// FMC SDRAM последовательность инициализации устройства

// Шаг 1

// Строки: [9:0]
tmp |= FMC_ColumnBits_Number_9b;
// Столбцы: [13:0]
tmp |= FMC_RowBits_Number_13b;
tmp |= FMC_NORSRAM_MemoryDataWidth_16b;
tmp |= FMC_InternalBank_Number_4;
// CL: Cas Latency = 3 цикла
tmp |= FMC_CAS_Latency_3;
tmp |= FMC_Write_Protection_Disable;
tmp |= FMC_SDClock_Period_2;
tmp |= FMC_Read_Burst_Enable;
tmp |= FMC_ReadPipe_Delay_1;
// FMC SDRAM bank initialization

// FMC SDRAM control configuration. Банк 1.
FMC_Bank5_6->SDCR[0] = tmp;

// Шаг 2

// Тайминги для 90 Mhz на SD. Частота (180Mhz/2)
// TMRD: 2 цикла ожидания
tmp = 2-1;
// TXSR: min=70ns (7x11.11ns)
tmp |= (7-1)<<4;
// TRAS: min=42ns (4x11.11ns) max=120k (ns)
tmp |= (4-1)<<8;
// TRC: min=70 (7x11.11ns)
tmp |= (7-1)<<12;
// TWR: min=1+ 7ns (1+1x11.11ns)
tmp |= (2-1)<<16;
// TRP: 20ns => 2x11.11ns
tmp |= (2-1)<<20;
// TRCD: 20ns => 2x11.11ns
tmp |= (2-1)<<24;

// FMC SDRAM тайминги. Банк 1.
FMC_Bank5_6->SDTR[0] = tmp;

// Шаг 3

// Разрешение команд
tmp = FMC_Command_Mode_CLK_Enabled;
tmp |= FMC_Command_Target_bank1;
// FMC_AutoRefreshNumber
tmp |= (1-1)<<5;
// FMC_ModeRegisterDefinition
tmp |= 0<<9;
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
// Послать комманду
FMC_Bank5_6->SDCMR = tmp;

// Шаг 4

// Задержка 100мс
hDelay(100);

// Шаг 5

// Сконфигурировать PALL (precharge all)
tmp = FMC_Command_Mode_PALL;
tmp |= FMC_Command_Target_bank1;
// FMC_AutoRefreshNumber
tmp |= (1-1)<<5;
// FMC_ModeRegisterDefinition
tmp |= 0<<9;
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
// Послать комманду
FMC_Bank5_6->SDCMR = tmp;

// Шаг 6

// Сконфигурировать Auto-Refresh
tmp = FMC_Command_Mode_AutoRefresh;
tmp |= FMC_Command_Target_bank1;
// FMC_AutoRefreshNumber
tmp |= (8-1)<<5;
// FMC_ModeRegisterDefinition
tmp |= 0<<9;
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
// Послать комманду
FMC_Bank5_6->SDCMR = tmp;

// Шаг 7

// Сконфигурировать load Mode регистр
tmp = FMC_Command_Mode_LoadMode;
tmp |= FMC_Command_Target_bank1;
// FMC_AutoRefreshNumber
tmp |= (8-1)<<5;
// FMC_ModeRegisterDefinition
// Запрограммировать mode register внешней памяти
tmp |= ((uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_3 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE)<<9;
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
// Послать комманду
FMC_Bank5_6->SDCMR = tmp;

// Шаг 8

// Установить счётчик регенерации памяти
// (7.81 us x Freq) - 20
FMC_Bank5_6->SDRTR |= (683<<1);

// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}

}