Ярлыки

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

воскресенье, 18 мая 2014 г.

RTC STM32F1xx

Calibration clock output


RTC clock calibration register (BKP_RTCCR). 

Bit 7 CCO: Calibration clock output
0: No effect
1: Setting this bit outputs the RTC clock with a frequency divided by 64 on the TAMPER pin.
The TAMPER pin must not be enabled while the CCO bit is set in order to avoid unwanted Tamper detection.
Note: This bit is reset when the V DD supply is powered off.

Event control register (AFIO_EVCR).

Bits 31:8 Reserved

Bit 7 EVOE: Event output enable
Set and cleared by software. When set the EVENTOUT Cortex output is connected to the
I/O selected by the PORT[2:0] and PIN[3:0] bits.

Bits 6:4 PORT[2:0]: Port selection
Set and cleared by software. Select the port used to output the Cortex EVENTOUT signal.
Note: The EVENTOUT signal output capability is not extended to ports PF and PG.
000: PA selected
001: PB selected
010: PC selected
011: PD selected
100: PE selected

Bits 3:0 PIN[3:0]: Pin selection (x = A .. E)
Set and cleared by software. Select the pin used to output the Cortex EVENTOUT signal.
0000: Px0 selected
0001: Px1 selected
0010: Px2 selected
0011: Px3 selected
...
1111: Px15 selected

Programm realisation for STM32F103:

AFIO->EVCR =0xAD; //PC13-calibration clock output enable
BKP->RTCCR |= BKP_RTCCR_CCO; //Setting this bit outputs the
//RTC clock with a frequency divided by 64 on the TAMPER pin


среда, 7 мая 2014 г.

STM32F103 RTC регистры настройки часов

Часы (RTC) представляют собой независимый таймер, который с помощью соответствующего программного обеспечения может выполнять функции часов и календаря. Питание может осуществлятся от отдельного источника Vbat от которого кроме регистров часов питается и так называемый Backup Domain (или батарейный домен). В него входят, кроме регистров RTC, LSE генератор и выводы с PC13 до PC15, обеспечивающие функционирование часов реального времени даже при отключенном питании на Vdd.  Для установки текущего значения счетчика (времени и даты) необходимо: 
  • включить тактирование интерфейса доступа к регистрам часов и Backup domain PWREN BKPEN выполнив команду 
          RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;
  • установить бит  DBP регистра PWR_CR, разрешающий доступ к  Backup domain
         PWR->CR |= PWR_CR_DBP;





суббота, 3 мая 2014 г.

Битовые операции

 Установка битов регистров
Язык Си не имеет в своём составе команд непосредственного сброса или установки разрядов переменной, однако присутствуют побитовые логические операции "И" и "ИЛИ", которые успешно используются для этих целей.
      Оператор побитовой логической операции "ИЛИ" записывается в виде вертикальной черты - "|" и может выполнятся между двумя переменными, а так же между переменной и константой. Напомню, что операция "ИЛИ" над двумя битами даёт в результате единичный бит, если хотя бы один из исходных битов находится с состоянии единицы. Таким образом для любого бита логическое "ИЛИ" с "1" даст в результате "1", независимо от состояния этого бита, а "ИЛИ" с логическим "0" оставит в результате состояние исходного бита без изменения. Это свойство позволяет использовать операцию "ИЛИ" для установки N-ого разряда в регистре. Для этого необходимо вычислить константу с единичным N-ным битом по формуле 2^N, которая называется битовой маской и выполнить логическое "ИЛИ" между ней и регистром, например для установки бита №7 в регистре SREG:
      (SREG | 128) — это выражение считывает регистр SREG и устанавливает в считанном значении седьмой бит, далее достаточно изменённое значение снова поместить в регистр SREG:
SREG = SREG | 128; // Установить бит №7 регистра SREG
Такую работу с регистром принято называть "чтение - модификация - запись", в отличие от простого присваивания она сохраняет состояние остальных битов без именения.
      Приведённый программный код, устанавливая седьмой бит в регистре SREG, выполняет вполне осмысленную работу - разрешает микроконтроллеру обработку программных прерываний. Единственный недостаток такой записи — в константе 128 не легко угадать установленный седьмой бит, поэтому чаще маску для N-ного бита записывают в следующем виде:  (1<<N) - это выражение на языке Си означает, число один, сдвинутое на N разрядов влево, это и есть маска с установленным N-ным битом. Тогда предыдущий код в более читабельном виде:
SREG = SREG | (1<<7)
   или ещё проще с использование краткой формы записи языка Си:
 SREG |= (1<<7);
которая означает - взять содержимое справа от знака равенства, выполнить между ним и регистром слева операцию, стоящую перед знаком равенства и записать результат в регистр или переменную слева.

Сброс битов в регистрах

Ещё одна логическая операция языка Си – побитовое "И", записывается в виде символа "&". Как известно, операция логического "И", применительно к двум битам даёт единицу тогда и только тогда, когда оба исходных бита имеют единичное значение, это позволяет применять её для сброса разрядов в регистрах. При этом используется битовая маска, в которой все разряды единичные, кроме нулевого на позиции сбрасываемого. Её легко получить из маски с установленным N-ным битом, применив к ней операцию побитного инвертирования:  ~(1<<N) в этом выражении символ "~" означает смену логического состояния всех битов маски на противоположные. Так, например, если (1<<3) в двоичном представлении – 00001000b,  то ~(1<<3) уже 11110111b. Сброс седьмого бита в регистре SREG будет выглядеть так:
SREG = SREG & (~ (1<<7));  или кратко: SREG &= ~ (1<<7);
В упомянутом ранее заголовочном файле для конкретного микроконтроллера приведены стандартные имена разрядов регистров специального назначения, например:
#define OCIE0 1
здесь #define – указание компилятору заменять в тексте программы сочетание символов "OCIE0" на число 1, то есть стандартное имя бита OCIE0, который входит в состав регистра TIMSK микроконтроллера Atmega64 на его порядковый номер в этом регистре. Благодаря этому установку бита OCIE0 в регистре TIMSK можно нагляднее записывать так:
TIMSK|=(1<<OCIE0);

Пример управления выводом NSS (CS) для режима мастер SPI шины
SPI1->CR1 |= SPI_CR1_SPE;                             //Enable the SPI1 by setting the SPE bit to 1
HAL_SPI_TransmitReceive(&hspi1, SPI1_Tx, SPI1_Rx,6,10);
SPI1->CR1 &= ~SPI_CR1_SPE;                       //Disable the SPI1  by setting the SPE bit to 0


Устанавливать или сбрасывать несколько разрядов регистра одновременно можно, объединяя битовые маски в выражениях оператором логического "ИЛИ":
     PORTA |= (1<<1)|(1<<4); // Установить выводы 1 и 4 порта A в единицу;
     PORTA&=~((1<<2)|(1<<3)); // Выводы 2 и 3 порта A сбросить в ноль

Проверка разрядов регистра на ноль и единицу.

Регистры специального назначения микроконтроллеров содержат в своём составе множество битов-признаков, так называемых "флагов”, уведомляющих программу о текущем состоянии микроконтроллера и его отдельных модулей. Проверка логического уровня флага сводится к подбору выражения, которое становится истинным или ложным в зависимости от того установлен или сброшен данный разряд в регистре. Таким выражением может служить логическое "И” между регистром и маской с установленным разрядом N на позиции проверяемого бита :
(REGISTR & (1<<N))
в этом выражении операция "И” во всех разрядах кроме N-ного даст нулевые значения, а проверяемый разряд оставит без изменения. Таким образом возможное значения выражения будут или 0 или 2^N, например для второго бита регистра SREG:

                                        если bit2=1                         если  bit2=0
SREG                      1  0  1  1  0  1  1  1                1  0  1  1  0  0  0  0
(1<<2)                    0  0  0  0  0  1  0  0                0  0  0  0  0  1  0  0
SREG&(1<<2)           0  0  0  0  0  1  0  0                0  0  0  0  0  0  0  0


Приведённое выражение можно использовать в условном операторе if (выражение) или операторе цикла while (выражение), которые относятся к группе логических, то есть воспринимают в качестве аргументов значения типа истина и ложь. Поскольку язык Си, приводя числовые значения к логическим, любые числа не равные нулю воспринимает как логическую истину, значение (REGISTR & (1<<N)) равное 2^N в случае установленного бита, будет воспринято как "истина".

     Если появляется необходимость при установленном бите N получить для нашего выражения логическое значение «ложь», достаточно дополнить его оператором логической инверсии в виде восклицательного знака - !(REGISTR & (1<<N)). Не следует путать его с похожим оператором побитовой инверсии (~) меняющим состояние битов разряда на противоположное. Логическая инверсия работает не с числовыми значениями, а с логическими, то есть преобразует истинное в ложное и наоборот. Такая конструкция приводится в DataSheet на Atmega как пример для ожидания установки бита UDRE в регистре UCSRA, после которого можно отправлять данные в UART:
while ( !( UCSRA & (1<<UDRE)) ) { } // Ждать установки UDRE
Здесь при сброшенном бите UDRE выражение ( UCSRA & (1<<UDRE)) даст значение ”ложь”, инвертированное  !( UCSRA & (1<<UDRE)) — ”истину”, и пока это так, программа будет выполнять действия внутри фигурных скобок, то есть не делать ничего (стоять на месте). Как только бит UDRE установится в единицу, программа перейдёт к выполнению действий следующих за конструкцией while(), например займётся отправкой данных в UART.

Изменение состояния бита регистра на противоположное.

Эту, с позволения сказать, проблему с успехом решает логическая операция побитного "ИСКЛЮЧАЮЩЕГО ИЛИ” и соответствующий ей оператор Си, записываемый в виде символа " ^ ”. Правило "исключающего или" с двумя битами даёт "истину” тогда и только тогда, когда один из битов установлен, а другой сброшен. Не трудно убедиться, что этот оператор, применённый между битовой маской и регистром, скопирует в результат биты стоящие напротив нулевых битов маски без изменения и инвертирует расположенные напротив единичных. Например, если: reg=b0001 0110 и mask=b0000 1111, то reg^mask=b0001 1001. Таким способом можно менять состояние светодиода, подключенного к пятому биту порта A:
#define LED 5 // Заменять в программе сочетание символов LED на число 5 (вывод светодиода).
     …
     PORTA ^=(1<< LED); // Погасить светодиод, если он светится и наоборот.

пятница, 2 мая 2014 г.

DWT - Data Watchpoint and Trace unit

  В STM32 регистры, используя которые, можно достаточно просто осуществлять подсчет времени исполнения различных участков кода.
 Один из этих регистров – DWT_CYCCNT, расположенный по адресу 0xE0001004, представляет собой счетчик тактов микроконтроллера. Чтобы запустить его на счет, необходимо установить младший бит (CYCCNTENA) регистра DWT_CONTROL.

#define    DWT_CYCCNT       *(volatile unsigned long *)0xE0001004
#define    DWT_CONTROL   *(volatile unsigned long *)0xE0001000
#define    SCB_DEMCR         *(volatile unsigned long *)0xE000EDFC

  SCB_DEMCR |= 0x01000000;
  DWT_CONTROL|= 1; // enable the counter
  DWT_CYCCNT  = 0;
  for(i=0;i<1000;i++){};
  time=DWT_CYCCNT;


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

#define    DWT_CYCCNT       *(volatile uint32_t *)0xE0001004
#define    DWT_CONTROL     *(volatile uint32_t *)0xE0001000
#define    SCB_DEMCR         *(volatile uint32_t *)0xE000EDFC

static inline uint32_t DWT_Get(void)
{
    return DWT_CYCCNT;
}
void init_dwt()
{
    SCB_DEMCR  |= 0x01000000;
    DWT_CYCCNT  = 0;
    DWT_CONTROL|= 1;                    // enable the counter
}

int main(void)
{
init_dwt();
DWT_CYCCNT=0;                             // сброс счётчика цилов процессора
DoSome();
uint32_t cycles=DWT_CYCCNT;      // чтение количества циклов
}
===========================================================
организация  задержки

uint32_t DWT_Get(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;return DWT_CYCCNT;
}
__inline
uint8_t DWT_Compare(int32_t tp)
{
&nbsp;&nbsp;&nbsp;&nbsp;return (((int32_t)DWT_Get() - tp) < 0);
}

void DWT_Delay(uint32_t us) // microseconds
{
&nbsp;&nbsp;&nbsp;&nbsp;int32_t tp = DWT_Get() + us * (SystemCoreClock/1000000);
&nbsp;&nbsp;&nbsp;&nbsp;while (DWT_Compare(tp));
}
==========================================================
uint32_t DWT_Get(void)
{
    return DWT_CYCCNT;
}
__inline
uint8_t DWT_Compare(int32_t tp)
{
    return (((int32_t)DWT_Get() - tp) < 0);
}

void DWT_Delay(uint32_t us) // microseconds
{
    int32_t tp = DWT_Get() + us * (SystemCoreClock/1000000));
    while (DWT_Compare(tp));

}


If your Cortex M microcontroller  have DWT  (Data Watchpoint and Trace) unit, you can use its register to count the number of cycles in which some code is executed. This could be useful for performance measuring. Simple cycle counter on ARM microcontroller  having DWT unit could be implemented like this:

#include <stdint.h>

volatile uint32_t count = 0;

// addresses of registers
volatile uint32_t *DWT_CONTROL = (uint32_t *)0xE0001000;
volatile uint32_t *DWT_CYCCNT = (uint32_t *)0xE0001004; 
volatile uint32_t *DEMCR = (uint32_t *)0xE000EDFC; 

// enable the use DWT
*DEMCR = *DEMCR | 0x01000000;

// Reset cycle counter
*DWT_CYCCNT = 0; 

// enable cycle counter
*DWT_CONTROL = *DWT_CONTROL | 1 ; 

// some code here
// .....

// number of cycles stored in count variable
count = *DWT_CYCCNT;

The DWT is an optional debug unit that provides watchpoints, data tracing, and system profiling for the processor.A full DWT contains four comparators that you can configure as 
  • hardware watchpoint
  • an ETM trigger
  • a PC sampler event trigger
  • a data address sampler event trigger.

The first comparator, DWT_COMP0, can also compare against the clock cycle counter, CYCCNT. You can also use the second comparator, DWT_COMP1, as a data comparator. A reduced DWT contains one comparator that you can use as a watchpoint or as a trigger. It does not support data matching. The DWT if present contains counters for:

  • clock cycles (CYCCNT)
  • folded instructions
  • Load Store Unit (LSU) operations 
  • sleep cycles 
  • CPI, that is all instruction cycles except for the first cycle
  • interrupt overhead.

Note
An event is generated each time a counter overflows.
You can configure the DWT to generate PC samples at defined intervals, and to generate interrupt event information.
The DWT provides periodic requests for protocol synchronization to the ITM and the TPIU, if the your implementation includes the Cortex-M3 TPIU.

Lists the DWT registers. Depending on the implementation of your processor, some of these registers might not be present. Any register that is configured as not present reads as zero.


a. Possible reset values are:
0x40000000 if four comparators for watchpoints and triggers are present
0x4F000000 if four comparators for watchpoints only are present
0x10000000 if only one comparator is present
0x1F000000 if one comparator for watchpoints and not triggers is present
0x00000000 if DWT is not present.

DWT registers are described in the ARMv7M Architecture Reference Manual. Peripheral Identification. Component Identification registers are described in the ARM CoreSight Components Technical Reference Manual.

Note
• Cycle matching functionality is only available in comparator 0.
• Data matching functionality is only available in comparator 1.
• Data value is only sampled for accesses that do not produce an MPU or bus fault. The PC is sampled irrespective of any faults. The PC is only sampled for the first address of a burst.
• The FUNCTION field in the DWT_FUNCTION1 register is overridden for comparators given by DATAVADDR0 and DATAVADDR1 if DATAVMATCH is also set in DWT_FUNCTION1. The comparators given by DATAVADDR0 and DATAVADDR1 can then only perform address comparator matches for comparator 1 data matches.
• If the data matching functionality is not included during implementation it is not possible to set DATAVADDR0, DATAVADDR1, or DATAVMATCH in DWT_FUNCTION1. This means that the data matching functionality is not available in the implementation. Test the availability of data matching by writing and reading the DATAVMATCH bit in DWT_FUNCTION1. If this bit cannot be set then data matching is unavailable.
• PC match is not recommended for watchpoints because it stops after the instruction. It mainly guards and triggers the ETM.


четверг, 1 мая 2014 г.

Keil System Viewer

При использовании Keil 4.74 Win7x64 с 32F103C8 и ST-linkV2 исчезают все пункты подменю периферии в System Viewer. Решение проблемы - нужно выбрать "System-Viewer File (.Sfr)" в опциях проекта, вкладка "Target". Файл для F103 находится тут Keil\ARM\SFD\ST\STM32F1xx\STM32F103xx.SFR. После установки данного файла появляются все системные переменные, доступные для просмотра. Для других серий выбирается соответствующий файл из каталога. Для переносимости проекта можно соответствующий файл перенести в каталог проекта.


среда, 30 апреля 2014 г.

Модернизация STM32VL DISCOVERY STlink в STM32F103 DISCOVERY Stlink/V2

    Одной из первых отладочных плат от STMicroelectronics была выпущена плата STM32VLDISCOVERY с процессором STM32F100RB и программатором  STlink. Недостатком данного программатора является отсутствие процесса трассировки. И кроме того в качестве отлаживаемого  применен не очень быстрый процессор, работающей на предельной тактовой частоте 24 Мгц.
    Данную плату довольно легко можно модернизировать. Процессор, стоящий на плате без каких либо изменений можно заменить на например STM32F103RB или другой подобный из 103 серии в корпусе QFTP64. Данная замена оправдана тем, что данная линейка процессоров полностью поддерживается в отладчике Keil. Кроме того существует огромное количество примеров для работы с этим типом процессоров.
    Для переделки STlink в STlink/V2 необходимо сделать следующее:

1. Необходимо заменить прошивку микросхемы STM32F103C8 на которой  собран программатор. Для этого можно воспользоваться Flash loader demonstrator которая позволяет с помощью штатного загрузчика изменить прошивку в самом программаторе. Для этого нам необходимо подключиться к выводам USART1_TX она же PA9 (30 вывод) и USART1_RX она же PA10 (31 вывод) - по ним будет осуществляться программирование процессора. А также к выводам BOOT0 (44 вывод) для перехода в режим встроенного загрузчика в системной памяти процессора и RST (7 вывод). Выводы 31 и 30 лучше всего подсоединить к пустым выводам (NC) на плате соответственно слева и справа (2-е выводы сверху). Процедура прогаммирования описывалась тут и тут. Вывод BOOT1(PB2) остается подключенным к земле. Прошивку для заливки в процессор программатора можно скачать тут. А саму программу Flash loader demonstrator тут.

2. После этого необходимо на процессоре программатора соединить PB12 (вывод 25)  и PB14 (вывод 27).

3. Соединить вывод PB3 он же JTDO (вывод 55 отлаживаемого процессора STM32F103RB) и PA10 он же TSWO (вывод 31 процессора программатора).

    В результате данной модернизации в среде Keil данный программатор определяется как STlink/V2.



вторник, 22 апреля 2014 г.

CMSIS ::Device:Startup

In actual file names, <device> is the name of the microcontroller device.

startup_<device>.s   file with reset handler and exception vectors

system_<device>.c   configuration file for basic device setup (clock and memory BUS)

<device>.h                include file for user code access to the microcontroller device.

The <device>.h header file is included in C source files and defines:

 Peripheral Access with standardized register layout.
 Access to Interrupts and Exceptions and the Nested Interrupt Vector Controller (NVIC).
 Intrinsic Functions to generate special instructions, for example to activate sleep mode.
 Systick Timer (SYSTICK) functions to configure and start a periodic timer interrupt.
 Debug Access for printf-style I/O and ITM communication via on-chip CoreSight.

mdk5-getting-started

STM32DBG.INI: STM32 Debugger Initialization File

Chek Load application at startup and select Initialization File

File  STM32DBG.INI  for the STLinkV2

/******************************************************************************/
/* STM32DBG.INI: STM32 Debugger Initialization File                           */
/******************************************************************************/
// <<< Use Configuration Wizard in Context Menu >>>                           //
/******************************************************************************/
/* This file is part of the uVision/ARM development tools.                    */
/* Copyright (c) 2005-2007 Keil Software. All rights reserved.                */
/* This software may only be used under the terms of a valid, current,        */
/* end user licence from KEIL for a compatible version of KEIL software       */
/* development tools. Nothing else gives you the right to use this software.  */
/******************************************************************************/
FUNC void DebugSetup (void) {
// <h> Debug MCU Configuration
//   <o1.0>    DBG_SLEEP     <i> Debug Sleep Mode
//   <o1.1>    DBG_STOP      <i> Debug Stop Mode
//   <o1.2>    DBG_STANDBY   <i> Debug Standby Mode
//   <o1.5>    TRACE_IOEN    <i> Trace I/O Enable
//   <o1.6..7> TRACE_MODE    <i> Trace Mode
//             <0=> Asynchronous
//             <1=> Synchronous: TRACEDATA Size 1
//             <2=> Synchronous: TRACEDATA Size 2
//             <3=> Synchronous: TRACEDATA Size 4
//   <o1.8>    DBG_IWDG_STOP <i> Independant Watchdog Stopped when Core is halted
//   <o1.9>    DBG_WWDG_STOP <i> Window Watchdog Stopped when Core is halted
//   <o1.10>   DBG_TIM1_STOP <i> Timer 1 Stopped when Core is halted
//   <o1.11>   DBG_TIM2_STOP <i> Timer 2 Stopped when Core is halted
//   <o1.12>   DBG_TIM3_STOP <i> Timer 3 Stopped when Core is halted
//   <o1.13>   DBG_TIM4_STOP <i> Timer 4 Stopped when Core is halted
//   <o1.14>   DBG_CAN_STOP  <i> CAN Stopped when Core is halted
// </h>
  _WDWORD(0xE0042004, 0x00000027);  // DBGMCU_CR
}
DebugSetup();                       // Debugger Setup


File  conf_STM32F10_SWO.ini   for ULINK2

/*-------------------------------------------------------------------
** Define the function to enable the trace port
**-----------------------------------------------------------------*/
FUNC void EnableTPIU(void) {

  _WDWORD(0xE0042004, 0x00000020);    // Set asynchronuous communication via DBGMCU_CR
}

/*-------------------------------------------------------------------
** Invoke the function at debugger startup
**-----------------------------------------------------------------*/
EnableTPIU();

четверг, 17 апреля 2014 г.

Debug (printf) Viewer

Используя технологию ITM (Instrumentation Trace Macrocell) можно организовать вывод функции printf используя небольшой код, вводимый в
программу пользователя. Для этого в начало файла с функцией main необходимо добавить строку:

#define ITM_Port8(n) (*((volatile unsigned char *)(0xE0000000+4*n))) 

после этого становится возможным вывод переменных с помощью функции printf переменных: 

ITM_Port8(0) = value + 0x30; /* displays value in ASCII */ 
while (ITM_Port8(0) == 0); 
ITM_Port8(0) = 0x0D; 
while (ITM_Port8(0) == 0); 
ITM_Port8(0) = 0x0A;

В настройках отладчика на вкладке Debug-Trace необходимо установить "птичку" для порта ITM0, снять "птичку" с пунктов On Data R/W Sample, EXCTRC и PC Sample. (для снятия излишней нагрузки на SWO port).
После этого в отладчике выбрав на вкладке View/Serial Windows Debug (printf) Viewer после запуска программы в отладчике мы увидим в окне результат работы функции printf.

среда, 9 апреля 2014 г.

Unique ID for STM32

Прочитать Unique ID очень легко, нужно лишь считать 3 32-битных значения, начиная с адреса 0x1FFFF7E8 (или 0x1FFF7A10 в случае STM32F4)..

static unsigned long *Unique_ID = (uint32_t *)0x1FFFF7E8;
unsigned long Unique_ID_0, Unique_ID_1, Unique_ID_2;
Unique_ID_0 = Unique_ID[0];
Unique_ID_1 = Unique_ID[1];
Unique_ID_2 = Unique_ID[2];


понедельник, 7 апреля 2014 г.

Выравнивание полей в структурах

По умолчанию для ARM все поля в структурах компилятор C выравнивает на границу 4 байта - это позволяет оптимизировать код, который поддерживает обращение к полям структуры. Если об этом забыть и не учитывать в программе (например, при работе со всеми полями структуры как одним блоком данных), то могут возникать неожиданные ошибки.

Выравнивание - это просто обеспечение кратности адресов определенному числу. Например, "выравнивание полей структуры на 4 байта" означает, что физический адрес каждого поля структуры делится нацело на 4.

По умолчанию в IAR для всех объектов памяти размером от 4 байт и более выравнивание включено. Это очень важно для буферов, работающих с прямым доступом к памяти (PDC) периферии ARM. Начальный адрес буфера памяти, работающий с PDC, должен быть обязательно выровнен на 4. Для работы со структурами протокола USB выравнивание должно быть наоборот выключено. Будьте внимательны, неправильно выбранное выравнивание может быть причиной неприятных ошибок!

В разных версиях IAR Embedded Workbench синтаксис для управления выравниванием может быть устроен по разному. В этой статье рассматриваются два варианта синтаксиса: для IAR версии 4.41A и для IAR версии 5.50.

[IAR 4.41A]

Для управления выравниванием используется специальная директива управления компилятором #pragma pack. По умолчанию, если #pragma pack не указано, то включено выравнивание на границу 32-битного слова (4 байта). Могут быть следующие варианты использования pack:

#pragma pack()  //восстанавливает состояние по умолчанию (выравнивание на 32 бита)
#pragma pack(n) //выравнивание на 1, 2, 4, 8 или 16 байт (указывается вместо n)
#pragma pack({push|pop}[,name] [,n])

[IAR 5.50]

Устранить поведение по умолчанию и убрать выравнивание позволяет ключевое слово __packed при объявлении структуры или директивы #pragma pack и #pragma data_alignment для модуля. В этом случае "пустоты", связанные с выравниванием, в структуре исчезают (экономится память, и не надо помнить о выравнивании), но несколько увеличивается код обработки структур. Пример использования __packed:

typedef __packed struct _Params
{
    u32 paramseed;
    u32 versionARM;
    u32 versionDSP;
    u8  backlight;
    u8  contrast;
    u8 minContrast;
    u8 maxContrast;
    char ProducerName[15];
    char ProducerURL[15];
    char ProducerEmail[15];
    u32 usbProdID;
    u32 usbVendorID;
    u16 CRC;
} TParams;

Будьте внимательными с размещением буферов в упакованной (__packed) структуре, если эти буфера работают с прямым доступом к памяти, лучше этого избегайте (определяйте буфер отдельно от упакованной структуры). Если все-таки решили поместить буфер в структуру с атрибутом __packed, то размещайте буфер в начале структуры, что гарантирует выравнивание его адреса на 4. Тогда прямой доступ к памяти будет всегда работать корректно.

воскресенье, 19 января 2014 г.

Все функции библиотеки  HAL, SPL используют для проверки своих аргументов макрос assert_param.
Этот макрос выполняет проверку выражения с участием проверяемого аргумента функции на равенство нулю. Если значение выражения равно нулю, то вызывается функция-обработчик ошибки аргумента assert_failed, в противном случае (выражение не равно нулю) проверка аргумента проходит успешно.
В своей программе вам необходимо реализовать функцию assert_failed.
В ней выводится сообщение об ошибке , название файла и номер строки кода, вызвавшей ошибку.


#ifdef  USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
 while (1)
 {
 }
}/* assert_failed */
#endif/*USE_FULL_ASSERT*/

Реализованная в вашем коде функция assert_failed используется только когда объявлен макрос USE_FULL_ASSERT. В противном случае весь отладочный код исключается из исходника.  Пример использования assert_param. 

void set_param(uint8_t * param, uint8_t value)
{
 assert_param( param != NULL);
 *param = value;
}/*set_param*/

Функция устанавливает значение параметра через указатель, передаваемый в качестве аргумента. Если макрос USE_FULL_ASSERT не объявлен, то можно считать , что строчки
assert_param( param != NULL) в коде просто нет, иначе в этом определении происходит проверка параметра.
Если указатель не определен, то значение param != NULL будет ложно и будет запущена функция assert_failed , которая выведет через USART название файла и номер строки с ошибкой, после чего зациклится, тем самым предотвратив присвоение значения по неопределенному адресу в памяти.
Вы совсем не обязаны использовать макрос assert_param в своем коде, но в коде библиотеки SPL он используется везде.
Функцию set_param можно реализовать с проверкой ошибок аргумента без применения assert_param.

#define ERROR (-1)
#define OK (0)
 
int set_param(uint8_t * param, uint8_t value)
{
 int r = ERROR;
 if ( param == NULL)
   return r;
 *param = value;
 r = OK;
 return r;
}/*set_param*/

суббота, 7 декабря 2013 г.

ARM command

Система команд в режиме THUMB
                                                 Система команд в режиме THUMB

МнемоникаКомандаРегистр-операнд группы HiРегистр-операнд группы LoВлияние на флаги регистра CPSR
ADCСложение с учетом переноса++
ADDСложение+++(1)
ANDЛогическое "И"++
ASRАрифметический сдвиг вправо++
BБезусловный переход+
BxxПереход по условию+
BICСброс битов (маскирование)++
BLПереход со ссылкой
BXПереход и смена режима ядра++
CMNСравнение с отрицанием++
CMPСравнение+++
EORИсключающее "ИЛИ"++
LDMIAГрупповая загрузка регистров+
LDRЗагрузка целого слова+
LDRBЗагрузка байта+
LDRHЗагрузка полуслова+
LSLЛогический сдвиг влево++
LDSBЗагрузка байта со знаком+
LDSHЗагрузка полуслова со знаком+
LSRЛогический сдвиг вправо++
MOVПересылка+++(2)
MULУмножение++
MVNПересылка с инверсией++
NEGИнверсия (побитовое "НЕ")++
ORRЛогическое "ИЛИ"++
POPИзвлечение регистров из вершины стека+
PUSHРазмещение регистров в вершине стека+
RORЦиклический сдвиг вправо++
SBCВычитание с переносом+ +
STMIAГрупповое сохранение регистров+
STRСохранение целого слова+
STRBСохранение байта+
STRHСохранение полуслова+
SWIПрограммное прерывание
SUBВычитание++
TSTПобитовая проверка++

STM32 Assembler

Арифметические операции
ADDADD R0, R1, Operand2
ADD R0, R1, 12bit const.
Сложение
R0 = R1 + R2
N, Z, C, V S
ADCADC R0, R1, R2
ADC R0, R1, 8bit const
Сложение с учётом переноса
R0 = R1 + R2 + C
N, Z, C, VS
ADDWADD R0, R1, 12bit const.Сложение с 12bit константойN, Z, C, V
SUBSUB R0, R1, R2
SUB R0, R1, 12bit const.
Вычитание
R0 = R1 - R2
N, Z, C, VS
SBCSBC R0, R1, R2
SBC R0, R1, 8bit const.
Вычитание с учётом переноса
R0 = R1 - R2 - C
N, Z, C, VS
SUBWSUB R0, R1, 12bit const.Вычитание с 12bit константойN, Z, C, V
RSBRSB R0, R1, R2
RSB R0, R1, 8bit const.
RSB R0, R1, R2, ASR#23
Вычитание с противоположным порядком
аргументов.
R0 = R2 - R1 или R0 = 8bit const - R1
N, Z, C, VS

Умножение. Деление.
MUL
MLA
MLS
R0 = R1 x R2
R0 = (R1 x R2) + R3
R0 = R3 - (R1 x R2)
Умножение. 32bit результат
Умножение и сложение
Умножение и вычитание
N, ZS
UMULL
UMLAL
SMULL
SMLAL
RLo, RHi = R2 x R3
RLo, RHi += R2 x R3
RLo, RHi = R2 x R3
RLo, RHi += R2 x R3
Умножение. 64bit результат
Умножение и сложение
Умножение со знаком. 64bit результат
Умножение со знаком и сложение
UDIV
SDIV
R0 = R1 / R2
R0 = R1 / R2
Деление без знака
Деление со знаком

Доступ к памяти
ADRADR R0, label +/- 12bit
ADR.W R0, label +/- 32bit
Загрузка адреса метки в регистр.
LDR
STR
LDR R0, [R1, #8bit const.]! - прединкремент
LDR R0, [R1], #8bit const. - постинкремент
LDRB R0, [R1] - без инкремента
STRB R0, [R1], #1
Загрузка/сохранение регистра в режиме
адресации со смещением.
B=байт, SB=байт со знаком (только загрузка)
H=полуслово, SH=полуслово со знаком (только загрузка)
LDR
STR
LDR R0, [R1, R2, {LSL#0..3}]
STR R0, [R1, R2, {LSL#0..3}]
Смещение задаётся третьим регистром.
B, SB, H, SH работают аналогично
LDR
LDRD
LDR R0, label
LDRD R0, R1, label
Смещение задаётся адресом метки.
B, SB, H, SH работают аналогично
Невозможно применить к STR/STRD.
LDRT
STRT
Непривилегированный доступ.
Аналогичны простому LDR/STR.
LDRD
STRD
LDRD R0, R1, [R2, #10bit const.]! - прединкремент
LDRD R0, R1, [R2], #10bit const. - постинкремент
LDRD R0, R1, [R2] - без инкремента
STRD R0, R1, [R2]
Загрузка/сохранение двух регистров в режиме
адресации со смещением.
Константа должна быть кратна 4.
LDM
STM
LDM R0, {R1-R3}
LDM R0!, {R1-R3} - постинкремент R0
IA, DB, FD, EA - см. описание
Загрузка/сохранение множества регистров.
IA - с увеличением адреса
DB - с уменьшением адреса.
PUSH
POP
PUSH {R0, R2-R7, R12}
POP {R0, R2-R7, R12}
Загрузка/чтение из стека
LDREX
STREX
LDREX R1, [R2, #10bit const.]
STREX R0, R1, [R2, #10bit const.]
Эксклюзивное чтение/запись регистра.
B=байт, H=полуслово.
CLREXCLREX (без параметров)Сброс признака эксклюзивного доступа.

Перемещение и обработка данных
MOV
MVN
MOV R0, R1
MOV R0, 16bit const.
MVN R0, R1
Загрузка/перемещение регистров
Загрузка 16-бит в мл. полуслово, сброс старшего
Перемещение регистра с инверсией
N, Z, C, VS
MOVTMOVT R0, 16bit const.Загр. 16bit в старшее полуслово. Младш. остаётся без изменений.
CMP
CMN
CMP R0, R1
CMN R0, R1
Сравнение
Сравнение с противоположным знаком
N, Z, C, VS
TSTTST R0, Operand2Проверить значение битов по маскеN, Z, CS
TEQTEQ R0, Operand2Проверить равенство двух величинN, ZS
REV
REV16
REVSH
RBIT
REV R0, R1Изменение порядка битов или байтов в слове
CLZCLZ R0, R1Подсчет количества ведущих нулей

Логические операции
AND
ORR
EOR
BIC
ORN
И
ИЛИ
Исключающее ИЛИ
Сброс битов по маске. И-НЕ
ИЛИ-НЕ
0 в маске сбрасывает биты. Второй Operand2 для всех команд
1 в маске устанавливает биты
1 в маске инвертирует биты
1 в маске сбрасывает биты
0 в маске устанавливает биты
N, Z, CS

Операции сдвига
ASR
LSL
LSR
ROR
RRX
Арифметический сдвиг вправо
Логический сдвиг влево
Логический сдвиг вправо
Циклический сдвиг вправо
Сдвиг вправо на 1 позицию через перенос



N, Z, CS

Ветвление. Подпрограммы.
BB labelПереход к метке
BXBX R0Переход по адресу в регистре
BLBL labelВыполнить подпрограмму label
BLXBLX R0Выполнить подпрограмму по адресу в регистре
BX LRBX LRВозврат из подпрограммы
CBZ
CBNZ
CBZ R0, label
CBNZ R0, label
Переход, если R0 = 0
Переход, если R0 != 0
TBB
TBH
TBB [R0, R1]
TBH [R0, R1, LSL #1]
Табличный переход по индексу. Короткий переход.
Длиннй переход
ITIT{x{y{z}}} condБлок условно исполняемых инструкций

Работа с битовыми полями
BFCBFC R0, #lsb, #widthСброс поля в ноль
BFIBFI R0, R1, #lsb, #widthКопирует младшие биты R1 в поле R0
UBFXUBFX R0, R1, #lsb, #widthКопирует поле R1 в мл. биты R0 с заполнением нулями
SBFXSBFX R0, R1, #lsb, #widthКопирует поле R1 в мл. биты R0 с расширением знака
UXTB
UXTH
UXTB R0, R1 {, ROR #8,16,24}Преобразование байта с заполнением нулями
Преобразование полуслова
SXTB
SXTH
SXTB R0, R1 {, ROR #8,16,24}Преобразование байта с расширением знака
Преобразование полуслова

Преобразование данных с насыщением
SSAT
USAT
SSAT Rd, #n, Rm {, shift #s}
USAT Rd, #n, Rm {, shift #s}
Число со знаком в число со знаком,
Число со знаком в число без знака
Q

Управление системой
MRS
MSR
MRS R0, PSR
MSR PSR, R0
Чтение/запись специальных регистров.
CPSIE
CPSID
Разрешение/запрет прерываний
WFEWFEОжидать событие
WFIWFIОжидать прерывание
BKPTТочка останова
DMB
DSB
DMBБарьер синхронизации доступа к ОЗУ
ISBISBСброс конвейера
SEVSEVДёрнуть ножкой события для внешних камней
SVCSVC 8bit const.Вызов системного сервиса
NOPNOP

Суффиксы условного исполнения
EQZ = 1Равенство
NEZ = 0Неравенство
CS, HSC = 1Больше или равно, беззнаковое сравнение
CC, LOC = 0Меньше, беззнаковое сравнение
MIN = 1Отрицательное значение, меньше нуля
PLN = 0Положительное значение, больше или равно нулю
VSV = 1Переполнение
V = 0Нет переполнения
HIC = 1 и Z=0Больше, беззнаковое сравнение
LSC = 0 или Z=1Меньше или равно, беззнаковое сравнение
GEN = VБольше или равно, знаковое сравнение
LTN != VМеньше, знаковое сравнение
GTZ = 0 и N = VБольше, знаковое сравнение
LEZ = 1 и N != VМеньше или равно, знаковое сравнение
AL1Безусловное исполнение

Встроенные псевдоинструкции компиллятора
MOV32MOV32 R0, 32bit const. (label)Загрузить слово в регистр.
LDRLDR R0, =labelЗагрузить 32bit адрес метки или #число
ADRLADRL R0, labelЗагрузить 32bit адрес метки