multikopter
multikopter
Блог строителя
44 posts
Я тут пишу... всякие записки. Чтобы не забыть что-то нужное.
Don't wanna be here? Send us removal request.
multikopter · 12 years ago
Text
Про свой bootloader для STM32
Цитата с форума :
Подскажите, как сделать безусловный переход по адресу. Бутлоадер записал прогу например по адресу 0х08010000. Находила примеры типа
Код
void (*FuncPtr)(void); FuncPtr=(void(*)(void))0x08010000;   //адресс куда переходим FuncPtr();
Но при выполнении последней строчки (вызов функции) FuncPtr() стшка вылетает в хард фолт. В чем может быть проблемма и как организовать прыжек из бутлоадера в основную программу? Может, можно сделать ассемблерную ставку типа goto или jump?
Цитата(batisto4ka @ Apr 22 2012, 21:02) 
Но при выполнении последней строчки (вызов функции) FuncPtr() стшка вылетает в хард фолт.
Нужно к адресу прибавить единицу. Это особенность режима Thumb. На досуге почитайте систему команд кортексов, посмотрите листинг дизассемблера.
Код
((void(*)(void))0x08010001)();
Цитата(batisto4ka @ Apr 23 2012, 00:02) 
Подскажите, как сделать безусловный переход по адресу. Бутлоадер записал прогу например по адресу 0х08010000.  как организовать прыжек из бутлоадера в основную программу?
Если приложение с��омпилировано для загрузки с адреса 0x8010000, по этому адресу будет размещаться таблица векторов. Вектор Reset находится по смещению +4, но это не точка входа, а указатель на нее. Поэтому нужно достать адрес из таблицы векторов и уже его присвоить указателю на функцию. Смотрим проверенный пример от ST:
Код
#define ApplicationAddress    0x08010000                                 //Начало нашего приложения typedef  void (*pFunction)(void); pFunction Jump_To_Application; uint32_t JumpAddress; if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000) //Проверяем, есть ли что-нибудь по адресу (там должно лежать значение SP для приложения, его кладет линкер)     {        JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);  //Адрес перехода из вектора Reset       Jump_To_Application = (pFunction) JumpAddress;                 //Указатель на функцию перехода       __set_MSP(*(__IO uint32_t*) ApplicationAddress);                //Устанавливаем SP приложения       Jump_To_Application();                                                       //Запускаем приложение     }     while(1);                                                                              // Если приложение не записано, Watchdog вернеет нас на начало бутлоадера
В приложении переносим таблицу векторов, ведь мы приходим сюда с активной таблицей векторов бутлоадера и первое же прерывание выкинет нас в обработчик бутлоадера, если он определен, а если не определен, то возможен переход неизвестно куда и его следствие - HardFault.
Код
void main(void) {     __disable_interrupt();                                                  // Запрещаем прерывания     NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x10000); //Адрес таблицы относительно начала Flash ... }
Ответы на все вопросы лежат в примерах из AN2557
0 notes
multikopter · 12 years ago
Text
Как перестроить последовательность в pgSQL
Не нравится то, что после ручных манипуляций со строками в таблице, значения в поле id (serial) не по порядку...
Как перестроить последовательность ?
Таблица называется dev_data_type_1, поле id.
Я создал новую последовательность (test_seq). Начало с нуля, инкремент на 1. Потом прокатил update dev_data_type_1 set id = nextval('test_seq'::regclass)+500000. Потом сбросил тек.значение последовательности test_seq в 0 и накатил снова, но без плюса - update dev_data_type_1 set id = nextval('test_seq'::regclass)
0 notes
multikopter · 12 years ago
Link
Еще одна суббота...
0 notes
multikopter · 12 years ago
Text
"Пончик" для параплана
Основание - круг диаметром 1400мм
Боковина - ткань высотой 240, потом тафета 120 см, потом прочная ткань с каналом под шнур.
Шнур выходит с двух сторон через люверсы.
Ручки пришиты в месте стыка основания и боковины.
0 notes
multikopter · 13 years ago
Text
RS232 + RS485
Вот думаю - "а как сделать так, чтобы в устройстве был и 232-ой и 485-ый интерфейс на одних контактах. С возможностью удаленного конфигурирования - а что же именно я хочу использовать ?"...
И таки я думаю, что я понял как это сделать.
ADM3485 может перевести линии А и Б в высокоимпендансное состояние. Сделать это просто - надо на RE подать "1", а DE посадить на нолик. Тогда передатчик отрубится и освободит выводы А и Б, а приемник переключит свой выход в Hi-Z.
Так, вроде как с RS-485 разобрался. Идем к 232-му.
MAX3232 может освободить линию передатчика и приемника... Делаем раз - на вход EN подаем логическую "1" - отключили приёмник. Делаем два - на вход SHDN подаем логический "0" - отключаем передатчик.
Ну вот - можно просто параллелить выхода драйверов и в теории один другому не будет мешать в случае управления ими.
Хотим RS-232 - на выводы драйвера 232-ого даём EN=0, SHDN=1 - включился 232-ой; на выводы драйвера 485-го даём RE=1, DE=0.
 Хотим RS-485 - на выводы драйвера 232-ого даём EN=1, SHDN=0 - 232-ой выключиться; на выводы драйвера 485-го даём сигналы по обстоятельству : приём - RE=0, DE=0; передача - RE=1, DE=1.
0 notes
multikopter · 13 years ago
Text
Клавиатура, автоповтор
// Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Reinitialize Timer's 0 value TCNT0=0xFB; if( (PINB&0x30) == 0x30 ) { key=Nothing; timer=0; return; } else { if( (PINB&0x30)==0x20 && timer==T1 ) { key=Up; } if( (PINB&0x30)==0x10 && timer==T1 ) { key=Down; } if( (PINB&0x30)==0x00 && timer==T1 ) { key=Nothing; } if( (PINB&0x30)==0x20 && timer==T1+T2 ) { key=Up; timer=T1+T2-T3; } if( (PINB&0x30)==0x10 && timer==T1+T2 ) { key=Down; timer=T1+T2-T3; } if( (PINB&0x30)==0x00 && timer==T1+T2 ) { key=Both; timer=0; } timer++; return; } }
0 notes
multikopter · 13 years ago
Text
bootloader stm32
typedef void    (*pFunction) (void);
pFunction       Jump_To_Application; u32             JumpAddress;
#include "stdio.h"
int             main(void) { Set_System(); GPIO_Config();
if (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_9) > 0) {       if (((*(vu32 *) 0x8004000) & 0x2FFF0000) == 0x20000000)       {          JumpAddress = *(vu32 *) (ApplicationAddress + 4);          Jump_To_Application = (pFunction) JumpAddress;          __MSR_MSP(*(vu32 *) ApplicationAddress);          Jump_To_Application();       } }
0 notes
multikopter · 13 years ago
Text
Чтобы не забыть.
3.1.3 Регулятор напряжения
Регулятор всегда включается после выхода устройства из режима сброса. Он работает в 3 режимах, которые зависят от режима работы контроллера.
Обычный режим. Регулятор обеспечивает полное питание для домена 1.8В (ядро, память, цифровая периферия)
Режим останова. Регулятор обеспечивает пониженное питание для домена 1.8В, сохраняются значения регистров и SRAM.
Режим ожидания. Регулятор отключен. Содержимое регистров и SRAM утеряно, кроме схемы ожидания и резервного домена.
3.3 Режимы с низким энергопотреблением  
По умолчанию, после сброса работает в режиме нормального энергопотребления. Режимы пониженного энергопотребления для снижения потребления энергии контроллером, когда нет необходимости в его функционировании (например при ожидании внешнего прерывания).
Контроллер может работать в следующих режимах:
Спящий режим – такирование ядра остановлено, периферия, в том числе и ядро, работает.
Режим останова – тактирование всех устройств отключено.
Режим ожидания – отключен домен 1.8В.
Снижение энергопотребления может быть осуществлено с помощью следующих методик:
Замедление тактирования системы
Прекращение тактирования периферии на шинах APB и AHB, когда они не используются.
3.3.1 Замедление системных частот
В обычном режиме величины системных частот (SYSCLK, HCLK, PCLK1, PCLK2) могут быть программно уменьшены с помощью предделителей. Предделители могут так же использоваться для замедления периферии перед погружением в спящий режим.
3.3.2 Отключение периферийного тактирования
В режиме нормального энергопотребления, сигналы HCLK и PCLKx для периферии и внешних запоминающих устройств могут быть отключены в любой момент для сохранения питания
3.3.3  Спящий режим
Вход в спящий режим
Вход в спящий режим осуществляется с помощью инструкций WFI (wait for interrupt) или WFE (wait for event). Есть возможность выбора механизма входа в спящий режим в зависимоти от бита SLEEPONEXIT:
Sleep-now: если бит SLEEPONEXIT сброшен, то устройство уходит в спящий режим как только была вызвана инструкция WFI или  WFE.
Sleep-on-exit: если бит SLEEPONEXIT установлен, то устройство входит в спящий режим как только произойдет выход из обработчика прерывания.
В спящем режиме все пины ввода-вывода сохраняют своё состояние.
Выход из спящего режима.
Если для входа в спящий режим была задействована инструкция  WFI, то выход контроллера из спящего режима может быть спровоцирован вызовом любого прерывания от периферии.
Если для входа в спящий режим была задействована инструкция WFE, то выход контроллера из спящего режима осуществляется как только происходит какое-либо событие. Это событие может быть сгенерировано:
за счет включения прерывания в регистре управления периферией, но не в  NVIC и за счет установки бита SEVONPEND в регистре управления ядром. После восстановления контроллера из WFE, бит ожидания периферийного прерывания и бит ожидания периферийного канала NVIC.
за счет конфигурирования внешнего или внутреннего EXTI в режиме событий.
3.3.4 Режим останова.
Режим останова базируется на режиме глубокой спячки ядра. В этом режиме останавливаются все генераторы тактовой частоты в 1.8В домене, а так же отключаются PLL, HSI и HSE RC.
В режиме останова все пины ввода-вывода сохраняют своё состояние.
Вход в режим останова. 
Вход может быть осущевствлен следующими способами:
Вызовом инструкций WFI или WFE пока:
Установлен бит SLEEPDEEP
Очищен бит PDDS в регистре PWR_CR
Выбран режим регулятора напряжения битом LPDS в регистре PWR_CR
Если во время перехода устройства в спящий режим происходит программирование флеш-памяти, то переход откладывается до завершения процесса программирования.
С доступом к домену APB ситуация аналогичная.
В режиме останова путем изменения соответствующих конфигурационных битов можно включить следующие возможности:
Независимый сторожевой таймер (IWDT): он может быть запущен с помощью своего регистра. Однажды запущен, он может быть остановлен только вводом контроллера в режим сброса.
Часы реального времени (RTC): с помощью бита RTCEC в своём регистре управления.
Внутренняя тактирующая RC-цепочка (LSI RC): с помощью бита LSION.
Внешний генератор на 32.768 кГц (LSE OSC): с помощью бита LSEON.
Выход из режима останова.
Если вход был инициирован с помощью WFI, то с помощью любой линии EXTI, сконфигурированной в режиме прерывания.
Если с помощью WFE, то с помощью любой линии EXTI, сконфигурированной в режиме события.
Во время выхода из режима останова HSI RC генератор выбран как основное системное тактирующее устройство.
3.4.5 Режим ожидания.
Режим ожидания – режим с минимальным энергоптреблением. Основан на режиме глубоко сна контроллера вместе с отключенным регулятором питания. В этом режиме 1.8В домен отключен, PLL и генераторы HSI и HSE аналогично отключены. Содержимое SRAM и всех регистров (кроме резервных) утеряно.
Вход в режим ожидания.
Вызовом инструкций WFI или WFE пока:
Установлен бит SLEEPDEEP
Установлен бит PDDS в регистре PWR_CR
Сброшен бит WUF в регистре (PWR_CSR)
Также можно включить следующие возможности:
Независимый сторожевой таймер (IWDT): он может быть запущен с помощью своего регистра. Однажды запущен, он может быть остановлен только вводом контроллера в режим сброса.
Часы реального времени (RTC): с помощью бита RTCEC в своём регистре управления.
Внутренняя тактирующая RC-цепочка (LSI RC): с помощью бита LSION.
Внешний генератор на 32.768 кГц (LSE OSC): с помощью бита LSEON.
Выход из режима ожидания.
Выход может быть осуществлен с помощью:
нарастающего фронта на пине  WKUP
нарастающему фронту будильника RTC
внешнего сигнала на пине NRST
сброса IWGT
Отладочный режим.
По усолчанию отладочное соединение таеряется при переходе контроллера в режим останова или ожидания, так как ядро больше не получает тактирующего сигнала.
Однако с помощью битов регистра DBGMCU_CR  можно включить возможность отладки контроллера в режимах с низким потреблением энергии.
3.3.6 Автовыход из режима пониженного энергопотребления 
Часы реального времени могут вызывать выход из режима пониженного энергоптребления без вызова прерывания. Можно настроить RTC на поддъем контроллера из этих режимов через определенные промежутки времени. Для этого можно выбрать 2 источника тактирующего сигнала для RTC с помощью битов RTCSEL[1:0] регистра управления RTC:
Внешний кварц на 32.768 кГц (LSE OSC)
Внутренняя RC-цепочка
Чтобы поднять устройство из режима останова с помощью события от будильника RTC необходимо сделать следующее:
 Настроить линию 17 EXTI на возрастающий фронт
Настроить RTC на генерацию будильника
3.4 Регистры управления питанием
3.4.1 Регистр управления питанием (PWR_CR)
31
9
8
7
6
5
4
3
2
1
0
Reserved
DBP
PLS[2:0]
PVDE
CSBF
CWUF
PDDS
LPDS
rw
rw
rw
rw
rw
rc_w1
rc_w1
rw
rw
Биты 31:9 – зарезервированы, всегда читаются как 0.
Бит 8 DBP (disable backup domain write protection) – отключение защиты от записи резервного домена.
0: Доступ к RTC и регистрам для резервного копирования отключен.
1:  Доступ к RTC и регистрам для резервного копирования включен.
Биты 7:5 PLS[2:0] (PVD level selection) – Выбор порога срабатывания детектора напряжения.
000: 2.2 В
001: 2.3 В
010: 2.4 В
011: 2.5 В
100: 2.6 В
101: 2.7 В
110: 2.8 В
111: 2.9 В
Бит 4 PVDE (power voltage detector enable) – включение детектора напряжения.
0 – PVD отключен.
1 – PVD включен.
Бит 3 CSBF (clear standby flag) – Очистить флаг ожидания.
Бит всегда читается как 0.
0 – не принесет результатаю.
1 – Очистка флага ожидания SBF.
Бит 2 CWUF (clear wakeup flag) – очистить флаг пробуждения.
Бит всегда читается как 0.
0 – не принесет результата.
1 – Очистка флага WUF после 2 тактов системного генератора.
Бит 1 PDDS (power down deepsleep) – бит перехода в глубокий сон с отключением питания. Работает вместе с LPDS.
0 – Вход в режим останова, когда CPU входит в режим глубокого сна. Статус регулятора зависит от бита LPDS.
1 – Вход в режим ожидания, когда CPU входит в режим глубокого сна.
Бит 0 LPDS (low-power deepsleep) – бит перехода в глубокий сон с режимом пониженного энергопотребления. Работает вместе с PDDS.
0 – Регулятор напряжения включен во время режима останова.
1 – Регулятор напряжения в режиме низкого энергопторебления во время режима останова.
3.4.2 Регистр управления/статусный регистр (PWR_CSR)
31
9
8
7
3
2
1
0
Reserved
EWUP
Reserved
PVDO
SDF
WUF
rw
r
r
r
Биты 31:9 – зарезервированы, ситаются как 0.
Бит 8 EWUP (Enable WKUP pin) – назначение пина WKUP.
0 – Пин WKUP используется как GPIO. Событие на WKUP не прерывает режим ожидания устройства.
1 – Пин WKUP используется для пробуждения устройства из режима ожидания по нарастающему фронту.
Биты 7:3 – зарезервированы, читаются как 0.
Бит 2 PVDO (PVD output) – флаг статуса программируемого регулятора напряжения. Бит устанавливается и сбрасывается аппаратно.
0: VDD / VDDA выше порога срабатывания PVD
1: VDD / VDDA ниже порога срабатывания PVD
Замечание: Во время режима ожидания PVD отключен, поэтом бит PVDO читается как 0 после выхода устройства из режима ожидания и после сброса, пока не установлен бит PVDE.
Бит 1 SBF (standby flag) – бит устанавливается и сбрасывается только POR/PDR или с помощью установки бита CSBF в регистре PWR_CR
0: Устройство не в режиме ожидания
1: Устройство в режиме ожидания
Бит 0 WUF (wakeup flag) – бит устанавливается аппаратно, а сбрасывается с помощью POR/PDR или с помощью установки бита CWUF в регистре PWR_CR.
0: Пробуждающего события нет
1: Пробуждающее событие пришло с пина WKUP или от будильника RTC.
 3.5 Программирование модуля управления питанием
void PWR_BackupAccessCmd (FunctionalState NewState)
Включает или отключает доступ к резервным регистрам и регистрам RTC.
Вход:
NewState – состояние разрешения доступа. Может быть либо ENABLE, либо DISABLE.
Выход:
Значения не возвращает.
void PWR_ClearFlag (uint32_t PWR_FLAG)
Очищает указанный флаг PWR.
Вход:
PWR_FLAG – указывает флаг, который надо сбросить. Прнимает следующие значения:PWR_FLAG_WU (wake up flag) и PWR_FLAG_SB (standby flag)
Выход:
Значения не возвращает.
void PWR_DeInit (void )
Сбрасывает значения регистров PWR к их первоначальному значению.
Вход:
Параметров нет.
Выход:
Значения не возвращает.
void void PWR_EnterSTANDBYMode (void )
Вводит устройство в режим ожидания.
Вход:
Параметров нет.
Выход:
Значения не возвращает.
void PWR_EnterSTOPMode (uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
Ввводит устройство в режим останова.
Вход:
PWR_Regulator – устанавливает состояние регулятора при входе в режим останова. Прнимает следующие значения: PWR_Regulator_ON (регулятор включен) иPWR_Regulator_LowPower (регулятор находится в режиме пониженного энергопотребления)
PWR_STOPEntry – устанавливает тип инструкции (WFE или WFI) с которой должен быть осуществлен вход режим останова. Принимает следующие значения:PWR_STOPEntry_WFI и PPWR_STOPEntry_WFE.
Выход:
Значения не возвращает.
FlagStatus PWR_GetFlagStatus (uint32_t PWR_FLAG)
Возвращает состояние указанного флага (установлен или нет).
Вход:
PWR_FLAG – указывает флаг, состояние которого надо проверить. Принимает следующие значения: PWR_FLAG_WU (wake up flag), PWR_FLAG_SB (standby flag) иPWR_FLAG_PVDO (PVD Output)
Выход:
Состояние флага. Варианты: SET или RESET
void PWR_PVDCmd (FunctionalState NewState)
Влючает или отключает детектор напряжения.
Вход:
NewState – статус детектора напряжения. Принимает следующие значения: ENABLE,DISABLE (standby flag) и PWR_FLAG_PVDO (PVD Output)
Выход:
Значения не возвращает.
void PWR_PVDLevelConfig (uint32_t PWR_PVDLevel)
Устанавливает порог срабатывания детектора напряжения.
Вход:
PWR_PVDLevel – вольтаж порога. Принимает следующие значения: отPWR_PVDLevel_2V2 (2.2 вольта) до PWR_PVDLevel_2V9 (2.9 вольта) с шагом 0.1 вольт.
Выход:
Значения не возвращает.
void PWR_WakeUpPinCmd (FunctionalState NewState)
Устанавливает возможность пробуждения контроллера по сигналу на пробуждающем пине.
Вход:
NewState – состояние возможности пробуждения. Принимает следующие значения:ENABLE и DISABLE.
Выход:
Значения не возвращает.
0 notes
multikopter · 13 years ago
Text
SMB380
SoftI2C_Init();
str[0] = SoftI2C_ReadByte(EEPROM_HW_ADDRESS, 0x14);
str[0] = str[0] && 0xE0;
SoftI2C_WriteByte(EEPROM_HW_ADDRESS, 0x14, str[0]);
while (1) {
SoftI2C_ReadBuffer(EEPROM_HW_ADDRESS, 0x00, buf, 8);
SoftI2C_Stop();
buf[2] = (buf[2] >> 6) && 0x03;
x = (buf[3] << 2) + buf[2];
if (x > 512) {
x = x - 1024;
}
buf[4] = (buf[4] >> 6) && 0x03;
y = (buf[5] << 2) + buf[4];
if (y > 512) {
y = y - 1024;
}
buf[6] = (buf[6] >> 6) && 0x03;
z = (buf[7] << 2) + buf[6];
if (z > 512) {
z = z - 1024;
}
sprintf(str, "%i\t%i\t%i\r\n", x, y, z);
USB_SIL_Write(EP1_IN, str, strlen(str));
for (i = 0; i < 500; i++) {
for (j = 0; j < 1000; j++)
;
}
}
0 notes
multikopter · 13 years ago
Text
Automatic TimeLapse with shift
Надо двигать коретку вдоль рельсы и периодически нажимать кнопку 'Shoot'
Исходные данные (setup): 1. длина рельсы L - 1 м. 2. скорость вращения лебедки S - 1 мм/шаг.
Переменные : 1. a. скорость перемещения - a [мм/сек]. b. кол-во снимков - b [шт]. 2. интервал съемки - с [c].
Если указан параметр b - пересчитываем его в параметр a : a =  S / b.
Считаем расстояние на рельсе между снимками : step = a * c. 
0 notes
multikopter · 13 years ago
Video
youtube
Не, ну не дура ли ?
0 notes
multikopter · 13 years ago
Text
Получение ответа от SIM900
Хочу получить ответ от SIM900. Весь входящий поток идет в кольцевой буфер через прерывание.
Процедурка "выгребает" строку. Начинается поиск строки с текущего указателя на чтение буфера. После выполнения процедуры указатель на чтение будет на сл. элементе буфера после строки. Т.е. мы "съедим" и лидирующие символы \r\n и завершающие \r\n.
Возвращает длину строки.
main.c
0 notes
multikopter · 13 years ago
Text
Снова SIM900
1. При отправке сообщения модему обязательно заключать фразу \r\n. 2. Ответ всегда обрамлен \r\n как спереди так и сзади.  3. Ответ на CGREG? выглядит так :
Tumblr media
0 notes
multikopter · 13 years ago
Photo
Tumblr media
Яблоко-мутант.
На фоне упаковка 2-литрового сока...
0 notes
multikopter · 13 years ago
Text
Про STM32 и USB
Для заметки : неплохо описан процесс подключения USB тут -> http://we.easyelectronics.ru/STM32/stm32-organizaciya-virtualnogo-com-porta.html
1 note · View note
multikopter · 13 years ago
Text
Право использовать PID/VID USB
Как мы уже знаем, ассоциация производителей-разработчиков интерфейса под названием USB определила, что для идентификации устройства служат такие параметры как Product ID (PID) и Vendor ID (VID). Распределением значений этих параметров занимается регистратор. Всё почти так же как и при регистрации домена ! Т.е. ты хочешь выпускать устройство, содержащее на борту интерфейс USB - будь добр, обратись в эту организацию, заплати пошлину и тебе выделят VID и один или несколько PID. И ты можешь считать, что никому больше эти реквизиты не выделят. Может спо��ойно писать firmware как для своего устройства, так и драйвер для ПК...
Многие вендоры, выпускающие чипы с интерфейсом USB для облегчения startup-а разработчику предоставляют библиотеки для работы с этим интерфейсом. И как правило в них уже заполнена какая-то связка PID/VID. Она "принадлежит" производителю. Производитель не против, чтобы разработчик использовал значения этих параметров на этапе разработки и тестирования hardware и firmware. 
Но в жизни бывают исключения. Как и в реальной жизни - яркий пример - чиновники... 
И вот может так получиться, что какой-то разработчик решил не усложнять себе жизнь и использовать чьи-то PID/VID. Вер��ятность того, что у пользователя будет и его устройство и устройство производителя с одними и теме же PID/VID - крайне мала... Но это же не правильно !
Так что меня сподвигло на написание этой статьи ? А занят я сейчас разработкой устройство, в котором присутствует интерфейс USB. Устройство построено на базе микроконтроллера от фирмы STMicroelectronics. И так как я раньше не имел дело с USB - я начал его изучение с стандартной библиотки от STM. В одном из файлов этой библиотеки (в качестве examples) есть описание устроства для шины USB :
/******************** (C) COPYRIGHT 2011 STMicroelectronics ******************** * File Name          : usb_desc.c * Author             : MCD Application Team * Version            : V3.3.0 * Date               : 21-March-2011 * Description        : Descriptors for Virtual Com Port Demo ******************************************************************************** * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. *******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h" #include "usb_desc.h"
/* USB Standard Device Descriptor */ const uint8_t Virtual_Com_Port_DeviceDescriptor[] =   {     0x12,   /* bLength */     USB_DEVICE_DESCRIPTOR_TYPE,     /* bDescriptorType */     0x00,     0x02,   /* bcdUSB = 2.00 */     0x02,   /* bDeviceClass: CDC */     0x00,   /* bDeviceSubClass */     0x00,   /* bDeviceProtocol */     0x40,   /* bMaxPacketSize0 */     0x83,     0x04,   /* idVendor = 0x0483 */     0x40,     0x57,   /* idProduct = 0x7540 */     0x00,     0x02,   /* bcdDevice = 2.00 */     1,              /* Index of string descriptor describing manufacturer */     2,              /* Index of string descriptor describing product */     3,              /* Index of string descriptor describing the device's serial number */     0x01    /* bNumConfigurations */   };
Ну, как бы всё понятно - PID 0x7540, VID 0x0483...  В прилагаемом драйвере виртуального COM-порта для этого устройства указано название  
Так о чем это я ?!
Ах да ! Задав поиск в google по ключевому слову Virtual_Com_Port_GetLineCoding я в первых же строчках ответа наткнулся на исходники устройства NaviCtrl от mikrokopter.de ! И что я тут увидел - хер Holger почему-то решил, что его коммерческий проект стоимостью за пол сотни евро можно продавать используя PID и VID из примеров STM... Вот ссылка на файл описания устройства USB из его проекта. Подправил название устройства и вперед ! Правда здорово ?!
И снизу :
const u8 Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL] = { VIRTUAL_COM_PORT_SIZ_STRING_SERIAL, /* bLength */ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ 'M',0, 'K',0, ' ',0, ' ',0, ' ',0, '1',0, '.',0, '0',0, '0',0, '0',0 }; /******************* (C) COPYRIGHT 2006 STMicroelectronics *****END OF FILE****/
Ну как бы всё... Мне конечно не сильно жалко, но как-то не правильно, да ?
Чуть позже...
Ой, а в драйвере он ничего и не собирался править ! Зачем тогда string-и поменял в исходниках - не понятно. Ведь все же знают, что девайс будет называться в системе так, как это в драйвере написано, но не как в описании устройства.
Далее - Getting a Vendor ID.
8 notes · View notes
multikopter · 14 years ago
Text
SIM900 и активная сессия
В SIM900_TCPIP_Application Note_V1.02 на странице 28 есть пункт 9 повествующий о чудотворном выводе DCD. Его чудотворность заключается в том, что по нему очень удобно оценивать состояние канала передачи данных в прозрачном режиме. Нет необходимости контролировать поток на наличие CLOSED - всё гораздо проще : если пин в активном состоянии (высокий лог.уровень) - соединения нет, если пин в неактивном состоянии (низкий лог.уровень) - соединение есть и активно. Удобно, не правда ли ? 
5 notes · View notes