Estoy tratando de escribir un controlador de metal desnudo para el STM32F302 en un tablero Nucleo-64. Estoy teniendo problemas para superar los primeros pasos y obtener el hardware para configurar el Reconocimiento de inicialización. Este controlador está escrito para ejecutarse junto con el marco del sistema operativo mbed. Si ese detalle es importante, tuve problemas por los cuales el firmware pasaría a un estado de error si llamara al constructor CAN que proporcionan (es cierto que la placa no tiene soporte técnico). bajo mbed OS 5, pero un ingeniero de ST me dijo que esto se debe a la cantidad de RAM estática).
Aquí están los fragmentos de código que son relevantes:
void can_initialize(unsigned int frequency)
{
// Setup the CAN registers
RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
RCC->APB1ENR |= RCC_APB1ENR_CANEN;
MY_CAN_PORT->MCR |= CAN_MCR_RESET;
// Set to init mode
can_setMode(CAN_MODE::INIT);
// Enable transmit and receive
MY_CAN_PORT->MSR |= (CAN_MSR_RXM | CAN_MSR_TXM);
// Set the frequency
can_setFrequency(frequency);
}
void can_setMode(CAN_MODE new_mode)
{
switch (new_mode)
{
case CAN_MODE::SLEEP:
MY_CAN_PORT->MCR |= CAN_MCR_SLEEP;
// Wait for acknowledgement from hardware
// SLAK = 1, INAK = 0
while (~(MY_CAN_PORT->MSR & CAN_MSR_SLAK)
|| (MY_CAN_PORT->MSR & CAN_MSR_INAK));
break;
case CAN_MODE::INIT:
MY_CAN_PORT->MCR |= CAN_MCR_INRQ;
if (my_mode == CAN_MODE::SLEEP)
{
MY_CAN_PORT->MCR &= ~CAN_MCR_SLEEP;
}
// Wait for the acknowledgement from hardware
// INAK = 1 indicates initialization mode
while (~(MY_CAN_PORT->MSR & CAN_MSR_INAK));
break;
case CAN_MODE::NORMAL:
// first make sure we aren't in loopback mode
if (MY_CAN_PORT->BTR & CAN_BTR_LBKM)
{
// go to init so we can modify loopback mode
can_setMode(CAN_MODE::INIT);
// clear loopback mode
MY_CAN_PORT->BTR &= ~CAN_BTR_LBKM;
can_setMode(CAN_MODE::NORMAL);
}
MY_CAN_PORT->MCR &= ~(CAN_MCR_INRQ);
// Wait for acknowledgement from hardware
// SLAK = 0, INAK = 0
while ((MY_CAN_PORT->MSR & CAN_MSR_SLAK)
|| (MY_CAN_PORT->MSR & CAN_MSR_INAK));
break;
case CAN_MODE::LOOPBACK:
// go to init so we can modify loopback mode
can_setMode(CAN_MODE::INIT);
// set loopback mode
MY_CAN_PORT->BTR |= CAN_BTR_LBKM;
can_setMode(CAN_MODE::NORMAL);
break;
}
my_mode = new_mode;
}
Estoy planeando usar el dispositivo en modo Loopback para realizar pruebas, por lo que actualmente no tengo nada conectado externamente. ¿Necesito un bus CAN de dos nodos para poner el periférico en modo Inicial?
Noté que hay una publicación extremadamente similar y probé algunas de las soluciones propuestas aquí: Error de tiempo de espera de inicialización CAN en STM32F4
Cosas que he probado en HW:
- Intenté conectar TX y RX directamente, aunque como no está enviando nada (creo) no debería ser necesario.
- También intenté vincular CANRX a 3V3 para emular que el bus se encuentre en un estado recesivo para los 11 bits, pero esto tampoco resolvió el problema.
- Probado en un segundo tablero idéntico.
A falta de conectar un segundo nodo, no estoy seguro de qué hacer desde aquí. Si hay algún truco en estos tableros en los que no estoy pensando o si hay más detalles necesarios para diagnosticar el problema, ¡hágamelo saber!