Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

CAN на STM32F103 не выходит из инициализации

Чт дек 01, 2022 11:13:41

Пытаюсь на F103 поднять CAN (т.к. сейчас это - самые дешевые МК с CAN, по ~45р на алиэкспрессе можно купить STM32F103C6T6, вот и надумал на их основе наделать для машины всяких всячин). Сам CAN там практически 1-в-1 похож на F0 за мелкой разницей. Но вот при настройке никак не выходит из состояния инициализации, флаг так и остается висеть. Погуглил: у многих была такая проблема, посоветовали подтянуть Rx к +5В. Подтянул 10-килоомным резистором. Ноль результата! На Rx имею +0.5В, как будто бы он в режиме PP out вместо OD in. Инициализирую вот так:
Код:
AFIO->MAPR |= AFIO_MAPR_CAN_REMAP_REMAP2;
GPIOB->CRH = (GPIOB->CRH & ~(CRH(8,0xf)|CRH(9,0xf))) |
                 CRH(8, CNF_AFOD | MODE_FAST) | CRH(9, CNF_AFPP | MODE_FAST);

Пробовал вместо AFOD поставить AFPP - фиг вам! Что за засада?

Добавлено after 1 hour 31 minute 42 seconds:
Странная штука происходит: даже без инициализации ног в режиме Test (включены SILM и LBKM), если подключен TJA1050, CAN не может выйти из инициализации. Если отключен - все ОК, пакеты отправляет и эхо их принимает!
Вот что за западло?
У меня до этого MCP2551 стоял, я его на TJA1050 поменял - все равно…

UPD: не, мой косяк: у дурных F103 же свой "особенный" способ настройки ног. В общем, моя "MODE_FAST" настраивала PB8 в режим output!..

Re: CAN на STM32F103 не выходит из инициализации

Пт дек 02, 2022 11:47:21

Там Rx надо конфигурить как инпут, а не AF

Re: CAN на STM32F103 не выходит из инициализации

Пт дек 02, 2022 14:39:13

Там mode_fast конфигурировал ногу как выход, я сам прокосячил со своими макросами. Работает, но в сеть не идут пакеты. В понедельник осциллом гляну.

Re: CAN на STM32F103 не выходит из инициализации

Сб дек 03, 2022 09:10:20

Дык скорости только на выход участвуют. ногу Tx в режим 9, Rx в режим 4.
Я когда на 103 с 072 вернулся, тоже пару часов на это убил.
Вот так только заработало, (PB8 & PB9) GPIOB->CRH = 0x92222294;

Re: CAN на STM32F103 не выходит из инициализации

Пн дек 05, 2022 18:55:03

Настраиваю PB8 в режим 4, PB9 - в режим 9. Запускаю данные. МК пытается отправить данные, но ничего не получается (+приемник ничего не принимает). Если с другой стороны пытаюсь данные отправить, тот МК тоже бесконечно пытается отправить, но STM32F103 не принимает...
И на TJA1050, и на MCP2551 одна и та же картина. Странно как-то.
Если отключаю провода - сразу же ругается, что никого на линии нет. Подключаю - не ругается, но отправить не может. И осциллограмма в CAN-шине странная: на CANH максимальный уровень сигнала всего лишь 3.8В, на CANL минимальный - 1В, хотя должно быть 5 и 0 соответственно, когда 0 передается! Потому, наверное, приемник ничего и не получает…

Добавлено after 4 minutes 13 seconds:
Хотя, нет: на "той стороне", которой линию проверяю, CAN через ISO1050, и тоже относительно земли уровни всего лишь на 1.5В размах имеют. Дифференциально когда осциллограф включаю, вижу меандр 3В.

Добавлено after 50 minutes 11 seconds:
Ай, дурень я, дурень! Инициализацию CAN я же с F0x2 скопипастил, а о том, что там CAN от 48МГц питается, а на F103 — от 36МГц, не подумал!
В общем, вот как инициализировать CAN на F103, чтобы все нормально работало:
Код:
void CAN_setup(uint16_t speed){
    LED_off(LED1);
    if(speed == 0) speed = oldspeed;
    else if(speed < 50) speed = 50;
    else if(speed > 3000) speed = 3000;
    oldspeed = speed;
    uint32_t tmout = 16000000;
    // Configure GPIO: PB8 - CAN_Rx, PB9 - CAN_Tx
    /* (1) Select AF mode (10) on PB8 and PB9 */
    /* (2) AF4 for CAN signals */
    RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPBEN;
    AFIO->MAPR |= AFIO_MAPR_CAN_REMAP_REMAP2;
    GPIOB->CRH = 0;
    GPIOB->CRH = (GPIOB->CRH & ~(CRH(8,0xf)|CRH(9,0xf))) |
                 CRH(8, CNF_FLINPUT | MODE_INPUT) | CRH(9, CNF_AFPP | MODE_NORMAL);
    /* Enable the peripheral clock CAN */
    RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
    /* Configure CAN */
    /* (1) Enter CAN init mode to write the configuration */
    /* (2) Wait the init mode entering */
    /* (3) Exit sleep mode */
    /* (4) Normal mode, set timing to 100kb/s: TBS1 = 4, TBS2 = 3, prescaler = 60 */
    /* (5) Leave init mode */
    /* (6) Wait the init mode leaving */
    /* (7) Enter filter init mode, (16-bit + mask, bank 0 for FIFO 0) */
    /* (8) Acivate filter 0 for two IDs */
    /* (9) Identifier list mode */
    /* (10) Set the Id list */
    /* (12) Leave filter init */
    /* (13) Set error interrupts enable (& bus off) */
    CAN1->MCR |= CAN_MCR_INRQ; /* (1) */
    while((CAN1->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) /* (2) */
        if(--tmout == 0) break;
    CAN1->MCR &=~ CAN_MCR_SLEEP; /* (3) */
    CAN1->MCR |= CAN_MCR_ABOM; /* allow automatically bus-off */

    CAN1->BTR =  2 << 20 | 3 << 16 | (4500/speed - 1); //| CAN_BTR_SILM | CAN_BTR_LBKM; /* (4) */
    CAN1->MCR &= ~CAN_MCR_INRQ; /* (5) */
    tmout = 16000000;
    while((CAN1->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) /* (6) */
        if(--tmout == 0) break;
    // accept ALL
    CAN1->FMR = CAN_FMR_FINIT; /* (7) */
    CAN1->FA1R = CAN_FA1R_FACT0 | CAN_FA1R_FACT1; /* (8) */
    // set to 1 all needed bits of CAN1->FFA1R to switch given filters to FIFO1
    CAN1->sFilterRegister[0].FR1 = (1<<21)|(1<<5); // all odd IDs
    CAN1->FFA1R = 2; // filter 1 for FIFO1, filter 0 - for FIFO0
    CAN1->sFilterRegister[1].FR1 = (1<<21); // all even IDs
    CAN1->FMR &= ~CAN_FMR_FINIT; /* (12) */
    CAN1->IER |= CAN_IER_ERRIE | CAN_IER_FOVIE0 | CAN_IER_FOVIE1 | CAN_IER_BOFIE; /* (13) */

    /* Configure IT */
    NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0); // RX FIFO0 IRQ
    NVIC_SetPriority(CAN1_RX1_IRQn, 0); // RX FIFO1 IRQ
    NVIC_SetPriority(CAN1_SCE_IRQn, 0); // RX status changed IRQ
    NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
    NVIC_EnableIRQ(CAN1_RX1_IRQn);
    NVIC_EnableIRQ(CAN1_SCE_IRQn);
    CAN1->MSR = 0; // clear SLAKI, WKUI, ERRI
    can_status = CAN_READY;
}

Скорость - в килободах.

Добавлено after 7 hours 10 minutes 51 second:
Вот, выложил на гитхаб
Ответить