STM32 новичку в ARM что к чему

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

Пытаюсь программно запустить бутлоадер на STM32F072. Вот такой код

Код: Выделить всё

void Jump2Boot(){
    void (*SysMemBootJump)(void);
    volatile uint32_t addr = 0x1FFFC800;
    RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
    SysTick-›CTRL = 0;
    SysTick-›LOAD = 0;
    SysTick-›VAL = 0;
    sysreset();
    __DSB();
    SYSCFG-›CFGR1 = 0x01;
    __DSB();__ISB();
    SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
    __set_MSP(*(uint32_t *)addr);
    SysMemBootJump();
}
не работает. Без `sysreset` - тоже не работает. В обоих случаях USB не отключается в системе (т.е. подтяжка остается поднятой).
Здесь пишут, что практически такой же код работает!
Что за чертовщина?
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3805356#p3805356"]Без `sysreset` - тоже не работает.[/uquote]C помощью SysReset ты попадаешь в аппаратный ресет и всё что написано дальше не имеет смысла. Если ты аппаратно поставишь Boot0 в "1", то попадёшь в загрузчик. Либо ты программно переходишь в загрузчик, то должен привести чип в начальное состояние, сделать ремап, установить стек и перейти по адресу.
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3805356#p3805356"]В обоих случаях USB не отключается в системе (т.е. подтяжка остается поднятой).[/uquote]А чего бы ей самой отключиться? Её руками надо отключить.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

VladislavS писал(а):C помощью SysReset ты попадаешь в аппаратный ресет
Не попадаю! Это - функция начальной инициализации таймеров и периферии. Просто пробовал ее вызывать, чтобы сбросить все прерывания и таймеры в умолчательное значение.
VladislavS писал(а):Если ты аппаратно поставишь Boot0 в "1", то попадёшь в загрузчик.
В смысле - можно просто подать на эту ножку 1 и перезагрузить МК? Но у меня там нет конденсатора, боюсь, не успеет. Но можно попробовать.
VladislavS писал(а):должен привести чип в начальное состояние, сделать ремап, установить стек и перейти по адресу
Вот и пытаюсь, но, судя по тому, что он либо просто перезагружается, либо где-то виснет, что-то идет не так.
VladislavS писал(а):Её руками надо отключить.
точно, сейчас попробую.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3805441#p3805441"]Вот и пытаюсь, но, судя по тому, что он либо просто перезагружается, либо где-то виснет, что-то идет не так.[/uquote]Отладчик? Не, не слышали.
Реклама
Эиком - электронные компоненты и радиодетали
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

VladislavS, хватит уже со всякой ересью приставать! Я не пользуюсь внутрисхемной отладкой и считаю ее бредом!
Итак, отключение подтяжки вручную (USB_BCDR_DPPU) ничего не меняет.
Если выкинуть отмену прерываний (__disable_irq()), то МК просто перезагружается. Если же не выкидывать — зависает.
Буду пробовать ногу в 1 выставить. Жаль, сразу кондер туда не подпаял.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3805446#p3805446"]Я не пользуюсь внутрисхемной отладкой и считаю ее бредом![/uquote]
Ну давай, давай :)

Добавлено after 1 minute 32 seconds:
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3805446#p3805446"]Итак, отключение подтяжки вручную (USB_BCDR_DPPU) ничего не меняет.[/uquote]Подождал пока хост заметит отключение?
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

Сделал так:

Код: Выделить всё

void Jump2Boot(){
    void (*SysMemBootJump)(void);
    volatile uint32_t addr = 0x1FFFC800;
    for(int i = 0; i < 7200000; ++i) nop();
    USB->BCDR &= ~USB_BCDR_DPPU; // deactivate pullup
    for(int i = 0; i < 7200000; ++i) nop();
    //sysreset();
    // reset systick
    SysTick->CTRL = 0;
    // disable all interrupts
    __disable_irq();
    NVIC->ICER[0] = 0xffffffff;
    NVIC->ICPR[0] = 0xffffffff;
    __DSB();__ISB();
    // Enable the SYSCFG peripheral.
    RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
    // remap memory to 0 (only for STM32F0)
    SYSCFG->CFGR1 = 0x01;
    __DSB();__ISB();
    SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
    // set main stack pointer
    __set_MSP(*((uint32_t *)addr));
    SysMemBootJump();
}
(уж ждать-то больше некуда). Бесполезно:

Код: Выделить всё

[2008912.252304] usb 1-7: USB disconnect, device number 17
[2008912.252551] pl2303 ttyUSB0: error sending break = -19
[2008912.252767] pl2303 ttyUSB0: pl2303 converter now disconnected from ttyUSB0
[2008912.252789] pl2303 1-7:1.0: device disconnected
[2008913.702173] usb 1-7: new full-speed USB device number 18 using xhci_hcd
[2008913.816199] usb 1-7: device descriptor read/64, error -71
[2008914.033219] usb 1-7: device descriptor read/64, error -71
[2008914.249225] usb 1-7: new full-speed USB device number 19 using xhci_hcd
[2008914.363118] usb 1-7: device descriptor read/64, error -71
[2008914.585212] usb 1-7: device descriptor read/64, error -71
[2008914.687252] usb usb1-port7: attempt power cycle
[2008915.315111] usb 1-7: new full-speed USB device number 20 using xhci_hcd
[2008915.315270] usb 1-7: Device not responding to setup address.
[2008915.519278] usb 1-7: Device not responding to setup address.
Судя по разнице времени, оно таки не зависает, а пытается что-то сделать: активирует подтяжку USB и ничего не происходит.

ногу Boot0 установить в единицу нельзя: это не Boot1, на ней нет GPIO! Схемотехнически я положился на то, что в интернетах у народа "все работает", думал программно переходить в DFU, чтобы новый вариант прошивки записать, пока буду все это дело писать и отлаживать. Для stlink'а тоже выводы оставил, но что-то он глючит у меня: то ли провода плохие, то ли еще что (да и если вдруг повезет, и прошивка прошьется и проверится, то reset'а все равно не происходит и приходится вручную проводочком об землю).

Похоже, надо колхозить проводок между свободной ногой и boot0 + кондер на 0.1мкФ туда.
Последний раз редактировалось Eddy_Em Ср мар 11, 2020 17:43:45, всего редактировалось 1 раз.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Глобальные прерывания не надо запрещать, они у Cortex-M0 разрешены по ресету. Я бы вот такой код перед переходом добавил.

Код: Выделить всё

  RCC->AHBRSTR = RCC_AHBRSTR_TSCRST   | RCC_AHBRSTR_GPIOFRST | RCC_AHBRSTR_GPIOERST | RCC_AHBRSTR_GPIODRST |
                 RCC_AHBRSTR_GPIOCRST | RCC_AHBRSTR_GPIOBRST | RCC_AHBRSTR_GPIOARST;
  RCC->APB1RSTR = RCC_APB1RSTR_CECRST    | RCC_APB1RSTR_DACRST    | RCC_APB1RSTR_PWRRST    | RCC_APB1RSTR_CRSRST  |
                  RCC_APB1RSTR_CANRST    | RCC_APB1RSTR_USBRST    | RCC_APB1RSTR_I2C2RST   | RCC_APB1RSTR_I2C1RST |
                  RCC_APB1RSTR_USART4RST | RCC_APB1RSTR_USART3RST | RCC_APB1RSTR_USART2RST | RCC_APB1RSTR_SPI2RST |
                  RCC_APB1RSTR_WWDGRST   | RCC_APB1RSTR_TIM14RST  | RCC_APB1RSTR_TIM7RST   | RCC_APB1RSTR_TIM6RST |
                  RCC_APB1RSTR_TIM3RST   | RCC_APB1RSTR_TIM2RST;
  RCC->APB2RSTR = RCC_APB2RSTR_DBGMCURST | RCC_APB2RSTR_TIM17RST | RCC_APB2RSTR_TIM16RST | RCC_APB2RSTR_TIM15RST |
                  RCC_APB2RSTR_USART1RST | RCC_APB2RSTR_SPI1RST  | RCC_APB2RSTR_TIM1RST  | RCC_APB2RSTR_ADCRST   | RCC_APB2RSTR_SYSCFGRST;
  RCC->AHBRSTR = 0;
  RCC->APB1RSTR = 0;
  RCC->APB2RSTR = 0;
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

VladislavS, спасибо! Заработало!
Вот не пойму: на кой черт все в интернетах пишут __disable_irq()?
Вставил ваш код после отключения прерываний - не заработало. Убрал отключение прерываний - все в порядке!
Руками дергать пуллап не нужно.
В общем, вот такой код полностью работает как надо:

Код: Выделить всё

void Jump2Boot(){
    void (*SysMemBootJump)(void);
    volatile uint32_t addr = 0x1FFFC800;
    // reset systick
    SysTick->CTRL = 0;
    // reset clocks
    RCC->APB1RSTR = RCC_APB1RSTR_CECRST    | RCC_APB1RSTR_DACRST    | RCC_APB1RSTR_PWRRST    | RCC_APB1RSTR_CRSRST  |
                    RCC_APB1RSTR_CANRST    | RCC_APB1RSTR_USBRST    | RCC_APB1RSTR_I2C2RST   | RCC_APB1RSTR_I2C1RST |
                    RCC_APB1RSTR_USART4RST | RCC_APB1RSTR_USART3RST | RCC_APB1RSTR_USART2RST | RCC_APB1RSTR_SPI2RST |
                    RCC_APB1RSTR_WWDGRST   | RCC_APB1RSTR_TIM14RST  | RCC_APB1RSTR_TIM7RST   | RCC_APB1RSTR_TIM6RST |
                    RCC_APB1RSTR_TIM3RST   | RCC_APB1RSTR_TIM2RST;
    RCC->APB2RSTR = RCC_APB2RSTR_DBGMCURST | RCC_APB2RSTR_TIM17RST | RCC_APB2RSTR_TIM16RST | RCC_APB2RSTR_TIM15RST |
                    RCC_APB2RSTR_USART1RST | RCC_APB2RSTR_SPI1RST  | RCC_APB2RSTR_TIM1RST  | RCC_APB2RSTR_ADCRST   | RCC_APB2RSTR_SYSCFGRST;
    RCC->AHBRSTR = 0;
    RCC->APB1RSTR = 0;
    RCC->APB2RSTR = 0;
    // Enable the SYSCFG peripheral.
    RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
    // remap memory to 0 (only for STM32F0)
    SYSCFG->CFGR1 = 0x01; __DSB(); __ISB();
    SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
    // set main stack pointer
    __set_MSP(*((uint32_t *)addr));
    // jump to bootloader
    SysMemBootJump();
}
Теперь остается лишь написать `make dfuboot`, а после заливки нажать кнопочку reset. И никаких внешних приблуд не нужно...
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; Не обязательно. Ремап без него работает.

Добавлено after 6 minutes 50 seconds:
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3805459#p3805459"]Вот не пойму: на кой черт все в интернетах пишут __disable_irq()?[/uquote]Процессоры разные бывают. Где-то надо, где-то нет.

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3805459#p3805459"]Руками дергать пуллап не нужно.[/uquote]Да, его RCC_APB1RSTR_USBRST сбрасывает.
Опытный кот
Аватара пользователя
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Сообщение baghear »

Добрый день вопрос FSMC, а именно по линиям Ax и NEy.
Как я понял, от x и y зависит адрес к которому будем обращаться.

В одном appnote нашел такую фразу.
Example: with NE2 and A4, the LCD base address will be 0x6400 0000 and 0x6400 0020;
with NE4 and A0, the LCD base address will be 0x6C00 0000 and 0x6C00 0002.
Подскажите как производить расчет адреса?
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="baghear",url="/forum/viewtopic.php?p=3823837#p3823837"]Подскажите как производить расчет адреса?[/uquote]
4 банка по 64МБ, базовый адрес - 0x6000'0000. Для NE2 и A4 добавляем 64МБ и устанавливаем 4-й бит, но это для 8-ми битного доступа, для 16-ти битного еще сдвигаем его на 1 влево.
Опытный кот
Аватара пользователя
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Сообщение baghear »

Что касается банков и вывода NEx понял.
Первый банк в свою очередь делится на 4 подбанка, это как-то влияет на адрес?
У меня NE1 A18, правильно ли понял для 16 битного доступа 0x6000'0000 и 0x60080000?
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="baghear",url="/forum/viewtopic.php?p=3823861#p3823861"]Первый банк в свою очередь делится на 4 подбанка, это как-то влияет на адрес?[/uquote]
Я не совсем правильно выразился, говоря про 4 банка я имел в виду именно подбанки в первом банке для NOR/SRAM.
У меня NE1 A18, правильно ли понял для 16 битного доступа 0x6000'0000 и 0x60080000?
Да, адреса правильные.
Опытный кот
Аватара пользователя
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Сообщение baghear »

Еще вопрос, для общение с дисплеем по fsmc делал так.

Код: Выделить всё

#define LCD_DATA 0x60020000
#define LCD_REG 0x60000000

void Lcd_Write_Index(uint16_t index)
{
   *(uint16_t *) (LCD_REG) = index;
}
////////////////////////
void Lcd_Write_Data(uint16_t data)
{
   *(uint16_t *) (LCD_DATA)= data;
}
///////////////////
А в китайском примере делают так

Код: Выделить всё

typedef struct
{
	vu16 LCD_REG;
	vu16 LCD_RAM;
} LCD_TypeDef;
		    
#define LCD_BASE        ((u32)(0x60000000 | 0x00080000))
#define LCD             ((LCD_TypeDef *) LCD_BASE)

void LCD_WR_REG(u16 data)
{ 
	LCD->LCD_REG=data;
}

void LCD_WR_DATA(u16 data)
{
	LCD->LCD_RAM=data;
}
Как это работает?
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

LCD - указатель на экземпляр структуры, лежащий по адресу 0x60080000, соответственно, LCD->LCD_REG - первые 16 байт по этому адресу, LCD->LCD_RAM - следующие 16 байт. Т.е. по сути, двухбайтовые данные, лежащие по адресам 0x60080000 и 0x60080002 соответственно.
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3823919#p3823919"]Т.е. по сути, двухбайтовые данные, лежащие по адресам 0x60080000 и 0x60080002 соответственно.[/uquote]
И работать оно будет только для A0.

Добавлено after 4 minutes 7 seconds:
[uquote="baghear",url="/forum/viewtopic.php?p=3823906#p3823906"]

Код: Выделить всё

*(uint16_t *) (LCD_REG) = index;
[/uquote]
А тут нужен (volatile uint16_t*), хотя с некоторыми компиляторами может работать и так.
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Да, там выходит, что DC вывод дисплея (ну или что там для выбора Data/Command) используется, получается фиксированным битом.
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Сообщение baghear »

И работать оно будет только для A0.
Точно!!!

Это работать не должно в моем случае!!!!

Добавлено after 1 hour 27 minutes 43 seconds:
Переписал код, дисплей заработал. Но возник вопрос, запись в регистр.

Код: Выделить всё

void LCD_WR_REG(u16 data)
{ 
	*(uint16_t *) (LCD_REG) = data;
}

Часть инициализации

Код: Выделить всё

LCD_WR_REG(0xff00);
	LCD_WR_DATA(0x80);
	LCD_WR_REG(0xff01);
	LCD_WR_DATA(0x09);
	LCD_WR_REG(0xff02);
	LCD_WR_DATA(0x01);

	LCD_WR_REG(0xff80);
	LCD_WR_DATA(0x80);
	LCD_WR_REG(0xff81);
	LCD_WR_DATA(0x09);
Видно что в регистр должны писаться 32-битные данные, почему это работает?
Последний раз редактировалось baghear Чт апр 09, 2020 13:46:02, всего редактировалось 1 раз.
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Откуда это видно?
Контактная информация:
Ответить

Вернуться в «ARM»