Перейти к содержанию
    

koluna

Участник
  • Постов

    1 133
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о koluna

  • Звание
    Профессионал
    Профессионал
  • День рождения 14.12.1979

Контакты

  • Сайт
    Array
  • ICQ
    Array

Посетители профиля

5 750 просмотров профиля
  1. Это я уже знаю, все осциллографом видно 🙂 Да, чувствую, что надо сделать как-то так, но как конкретно - пока не знаю. Сейчас там в цикле ожидание флагов, нужная комбинация не устанавливается и подвисаем: #define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */ Наверное, по таймауту надо выходить и формировать STOP.
  2. Другой вопрос. Если мы общаемся (чтение 1 байта) к устройству, которого нет на шине (адрес другой), то что в этом случае должно происходить? По сути мы получаем NAK. И что дальше? Сейчас опять подвисаю после отправления байта адреса: контроллер удерживает SCL в низком уровне, датчик - тоже. Кстати, датчик этот не умеет clock stretch.
  3. Да, начал разбираться с I2C, проверил и убедился сам в этом. Спасибо!
  4. Резисторы подтяжки изначально 4.7 к. Уменьшал до 1 к, увеличивал до 10 к - не влияет. От процессора до датчика по проводам 10-15 см.
  5. Если кто помнит - сообщите, пожалуйста, название чудо NXPшного мануала, про который тут речь.
  6. Функция инициализации. void I2C_init(I2C_TypeDef* I2Cx, uint32_t speed) { RCC_APB1PeriphClockCmd(I2Cx == I2C1 ? RCC_APB1Periph_I2C1 : RCC_APB1Periph_I2C2, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); delayMSec(10); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); I2C_InitTypeDef I2C_InitStructure; // I2C_StructInit(&I2C_InitStructure); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_ClockSpeed = speed; I2C_InitStructure.I2C_OwnAddress1 = 1; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_Init(I2Cx, &I2C_InitStructure); I2C_Cmd(I2Cx, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_Init(GPIOB, &GPIO_InitStructure); } Частоту пробовал разную, ситуация не меняется.
  7. STM32F100C8 + BMP280 - проблемы с I2C

    Здравстуйте! Столкнулся с проблемой при обмене между процессором и датчиком. Для начала пытаюсь считать из датчика всего 1 байт - идентификатор. Использую SPL, код простейший, таймауты пока не обрабатывал, но знаю где зависает (см. в коде). Датчик после обмена удерживает линию SDA в нуле (именно он, проверял отсоединяя его), Если линию SDA отсоединить, потом присоединить, то функция чтения завершается и возвращается правильный результат - x58. Приложил осциллограмму (верхний канал - SDA, нижний - SCL). Прошу помочь разобраться. uint8_t byte = I2C_single_read(I2C1, BMP280_ADDRESS << 1, 0xD0); ... uint8_t I2C_single_read(I2C_TypeDef* I2Cx, uint8_t HW_address, uint8_t addr) { uint8_t data; while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)); I2C_GenerateSTART(I2Cx, ENABLE); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2Cx, HW_address, I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2Cx, addr); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTART(I2Cx, ENABLE); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2Cx, HW_address, I2C_Direction_Receiver); while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_RECEIVED)); data = I2C_ReceiveData(I2Cx); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); I2C_AcknowledgeConfig(I2Cx, DISABLE); I2C_GenerateSTOP(I2Cx, ENABLE); while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)); // Зависает здесь!!! return data; }
  8. Как не читал? Читал. Только вот не все правильно делал... Какой? Вот вырезка из даташита: Что произойдет, если прочитать регистр данных без установленного RXNE? Лайк 🙂
  9. Вот как раз оно и проскакивало... одна одна из проблем... а оно отдельно не выключается... Да, я не сбрасывал ORE... Сбрасываются автоматом программной последовательностью: чтение регистра состояния и чтение регистра данных... txCnt портился. Ситуация была следующая: ведущее устройство при определенных обстоятельствах начинало постоянно без пауз что-то слать... Ведомое устройство (которое мы сейчас ризбираем) неправильно обрабатывало прерывания (возникала ошибка Overrun) и мы попадали в функцию обработчика передачи данных, в которой не было контроля как Вы написали, в результате - переполнение и т. д. По сути, выручил осциллограф, надо было его раньше включать 🤣 Искренне всех благодарю, спасибо большое за помощь!
  10. Оно давно так уже... наверное, изначально даже... просто не сразу заметил и сообщил об этом... Все бы ничего, наверное, но я через CLI отлаживаю и у меня пару вопросов: (gdb) backtrace #0 HardFault_Handler () at ./src/main.c:139 #1 <signal handler called> #2 0x0800165e in exchTXEHandler () at ./src/libs/exchange/exchange.c:361 #3 <signal handler called> #4 dbgout (level=level@entry=7, format=0x80017cb <EXCH_process+278> "H\377\367\222\370\276#+\200\245\347PN") at ./src/libs/dbg/dbg.c:19 #5 0x080017ca in waitForRequest (exchRes=0x20000f00 <exchRes.7248>, pt=0x20000f0c <ptChild.7247>) at ./src/libs/exchange/exchange.c:187 #6 EXCH_process (pt=0x20001fec) at ./src/libs/exchange/exchange.c:483 #7 0xf4f3f7fc in ?? () Backtrace stopped: previous frame identical to this frame (corrupt stack?) Что значат строки <signal handler called>. Видимо, строка Backtrace stopped: previous frame identical to this frame (corrupt stack?) говорит о том, что что-то пошло не так? Ранее, когда пользовался отладчиком, мне хватало информации, чтобы быстро найти ошибку. А сейчас слишком много нового и непонятного...
  11. Посмотрел листинг, не знаю, там черт ногу сломи - как интерпретировать... Как я понял, строка 0354 4FEA5000 lsr r0, r0, #1? 110:./src/libs/exchange/exchange.c **** if (temp == 0) 1563 .loc 1 110 36 is_stmt 0 view .LVU502 1564 0340 80EA0201 eor r1, r0, r2 111:./src/libs/exchange/exchange.c **** { 1565 .loc 1 111 16 view .LVU503 1566 0344 C907 lsls r1, r1, #31 1567 0346 03F1FF33 add r3, r3, #-1 1568 .LVL87: 119:./src/libs/exchange/exchange.c **** } 1569 .loc 1 119 22 view .LVU504 1570 034a 48BF it mi 1571 034c 80F48C70 eormi r0, r0, #280 1572 .LVL88: 119:./src/libs/exchange/exchange.c **** } 1573 .loc 1 119 22 view .LVU505 1574 .LBE126: 108:./src/libs/exchange/exchange.c **** { 1575 .loc 1 108 9 view .LVU506 1576 0350 13F0FF03 ands r3, r3, #255 1577 .LBB127: 119:./src/libs/exchange/exchange.c **** } 1578 .loc 1 119 22 view .LVU507 1579 0354 4FEA5000 lsr r0, r0, #1 1580 .LVL89: 121:./src/libs/exchange/exchange.c **** } 1581 .loc 1 121 13 is_stmt 1 view .LVU508 121:./src/libs/exchange/exchange.c **** } 1582 .loc 1 121 18 is_stmt 0 view .LVU509 1583 0358 4FEA5202 lsr r2, r2, #1 1584 .LVL90: 121:./src/libs/exchange/exchange.c **** } 1585 .loc 1 121 18 view .LVU510 1586 .LBE127: 108:./src/libs/exchange/exchange.c **** { 1587 .loc 1 108 49 is_stmt 1 view .LVU511 108:./src/libs/exchange/exchange.c **** { 1588 .loc 1 108 35 view .LVU512 108:./src/libs/exchange/exchange.c **** { 1589 .loc 1 108 9 is_stmt 0 view .LVU513 Как объяснить ситуацию, когда после перепрошивки МК Hard Fault всегда возникает сразу?
  12. Строка: dbgout(LOG_DEBUG, "[%s()] Wait for packet... ", __func__); Код поменял, сейчас немного по-другому, но тоже самое: (gdb) backtrace #0 HardFault_Handler () at ./src/main.c:139 #1 <signal handler called> #2 0x0800165e in exchTXEHandler () at ./src/libs/exchange/exchange.c:361 #3 <signal handler called> #4 dbgout (level=level@entry=7, format=0x80017cb <EXCH_process+278> "H\377\367\222\370\276#+\200\245\347PN") at ./src/libs/dbg/dbg.c:19 #5 0x080017ca in waitForRequest (exchRes=0x20000f00 <exchRes.7248>, pt=0x20000f0c <ptChild.7247>) at ./src/libs/exchange/exchange.c:187 #6 EXCH_process (pt=0x20001fec) at ./src/libs/exchange/exchange.c:483 #7 0xf4f3f7fc in ?? () Backtrace stopped: previous frame identical to this frame (corrupt stack?) void dbgout(const int32_t level, const char* format, ...) { UNUSED(level); va_list args; va_start(args, format); xvprintf(format, args); va_end(args); } Используется библиотека xprintf, переопределил для нее функцию вывода байта в USART1. Интерфейс, на котором сбои - USART2. Никак они не связаны. По сути - в нем проблема или где-то рядом... Передачу запускаю следующей функцией: static PT_THREAD(sendReply(PT* pt)) { PT_BEGIN(pt); txCnt = 0; txComplete = false; exchTxeEnable(); // Запускаем передачу. dbgout(LOG_DEBUG, "[%s()] Send packet %u bytes...\n", __func__, txSize); static bool tmp; do { PT_YIELD(pt); ENTER_CRITICAL(); tmp = txComplete; EXIT_CRITICAL(); } while(!tmp); dbgout(LOG_DEBUG, "[%s()] Send packet was completed.\n", __func__); txComplete = false; dbgout(LOG_DEBUG, "[%s()] Transaction trs: %u\n", __func__, transId); transId++; PT_END(pt); } В txSize размер пакета для передачи. Цикл с ожиданием для эксперимента. Ранее было просто PT_WAIT_UNTIL(pt, txComplete); Функция, вызываемая из обработчика (сейчас без проверки на переполнение): void exchTXEHandler(void) { exchWriteByte(exchBuff[txCnt]); txCnt++; if(txCnt == txSize) { exchTxeDisable(); txComplete = true; } } Вывод отладчика: (gdb) up 2 #2 0x0800165e in exchTXEHandler () at ./src/libs/exchange/exchange.c:361 361 exchWriteByte(exchBuff[txCnt]); (gdb) list 356 // } 357 //} 358 359 void exchTXEHandler(void) 360 { 361 exchWriteByte(exchBuff[txCnt]); 362 txCnt++; 363 364 if(txCnt == txSize) 365 { (gdb) frame #2 0x0800165e in exchTXEHandler () at ./src/libs/exchange/exchange.c:361 361 exchWriteByte(exchBuff[txCnt]); (gdb) info frame Stack level 2, frame at 0x20001f8c: pc = 0x800165e in exchTXEHandler (./src/libs/exchange/exchange.c:361); saved pc = 0xfffffff9 called by frame at 0x20001fac, caller of frame at 0x20001f7c source language c. Arglist at 0x20001f7c, args: Locals at 0x20001f7c, Previous frame's sp is 0x20001f8c Saved registers: r4 at 0x20001f7c, r5 at 0x20001f80, r6 at 0x20001f84, lr at 0x20001f88 Да, биты BFARVALID и PRECIS ERR установлены. Да, BFAR содержит корректный адрес: этот адрес 20002000 - RAM. Видимо, что-то оттуда попыталось прочитаться или записаться. Я выводил своим дебагом, там много кода... значение будет некорректным, наверное. Только в отладчике смотреть? Поставил брекпойнт на HardFault_Handler(). Вот информация при остановке: Breakpoint 1, HardFault_Handler () at ./src/main.c:126 126 dbgout(LOG_DEBUG, "\n[%s()] !!! System fault !!!\n", __func__); (gdb) list 121 // LR_read = *((uint32_t*) ((uint32_t) MSP_read + 5 * 4)); 122 // PC_read = *((uint32_t*) ((uint32_t) MSP_read + 6 * 4)); 123 124 125 126 dbgout(LOG_DEBUG, "\n[%s()] !!! System fault !!!\n", __func__); 127 dbgout(LOG_DEBUG, "[%s()] HFSR=x%08X\n", __func__, SCB->HFSR); 128 dbgout(LOG_DEBUG, "[%s()] CFSR=x%08X\n", __func__, SCB->CFSR); 129 dbgout(LOG_DEBUG, "[%s()] BFAR=x%08X\n", __func__, SCB->BFAR); 130 (gdb) info frame Stack level 0, frame at 0x20001f5c: pc = 0x8000354 in HardFault_Handler (./src/main.c:126); saved pc = 0xfffffff1 called by frame at 0x20001f7c source language c. Arglist at 0x20001f5c, args: Locals at 0x20001f5c, Previous frame's sp is 0x20001f5c pc = 0x8000354 - по этому адресу сбойная инструкция?
  13. Code::Blocks у меня. Я не разбирался как к нему отладчик прикручивать. Крайне редко им пользуюсь, обходилось всегда. Да, я пробовал. Не помогает... Длина всего пакета полностью. Да, спасибо, поправлю. Но если бы был таймаут, то мой программный дебаг сообщил бы об этом...
  14. При запуске сервера: koluna@lev:~$ openocd -f interface/jlink.cfg -c "transport select swd" -f target/stm32f1x.cfg Open On-Chip Debugger 0.12.0-rc1 Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html swd Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections Info : J-Link ARM V8 compiled Nov 14 2012 22:34:52 Info : Hardware version: 8.00 Info : VTarget = 3.313 V Info : clock speed 1000 kHz Info : SWD DPIDR 0x1ba01477 Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detected Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints Info : starting gdb server for stm32f1x.cpu on 3333 Info : Listening on port 3333 for gdb connections
×
×
  • Создать...