as the title implies, I want to use the CAN interface on the STM32F3Discovery board
I started with the demo-project(demos/ARMCM4-STM32F303-DISCOVERY) and copied the testhal functions for the CAN module.
The internal loopback had no problems, so I connected a SN65HVD233 transceiver to the CAN Pins and tried to extend the loopback, as the SN65HVD233 also has an internal loopback(LBKM->High)
PA11(CAN_RX) <-> Pin R at SN65...
PA12(CAN_TX) <-> Pin T at SN65...
Then I turned the alternative functions on the pins on.
But nothing happens. When I attach an oscilloscope to th CAN_TX line, I see nothing.
I have no idea, what to do now.
Below is my code. Could someone look at it and tell me, if I did something wrong or give me a hint for further investigation.
Thanks a lot
Code: Select all
#include "ch.h"
#include "hal.h"
/*
* Internal loopback mode, 500KBaud, automatic wakeup, automatic recover
* from abort mode.
*/
static const CANConfig cancfg = {
CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP,
CAN_BTR_SJW(0) | CAN_BTR_TS2(1) |
CAN_BTR_TS1(8) | CAN_BTR_BRP(6)
};
/*
* Receiver thread.
*/
static WORKING_AREA(can_rx_wa, 256);
static msg_t can_rx(void *p) {
EventListener el;
CANRxFrame rxmsg;
(void)p;
chRegSetThreadName("receiver");
chEvtRegister(&CAND1.rxfull_event, &el, 0);
while(!chThdShouldTerminate()) {
if (chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(100)) == 0)
continue;
while (canReceive(&CAND1, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE) == RDY_OK) {
/* Process message.*/
if(rxmsg.EID == 0x01234567){
palTogglePad(GPIOE, GPIOE_LED6_GREEN);
}
}
}
chEvtUnregister(&CAND1.rxfull_event, &el);
return 0;
}
/*
* Transmitter thread.
*/
static WORKING_AREA(can_tx_wa, 256);
static msg_t can_tx(void * p) {
CANTxFrame txmsg;
(void)p;
chRegSetThreadName("transmitter");
txmsg.IDE = CAN_IDE_EXT;
txmsg.EID = 0x01234567;
//txmsg.RTR = CAN_RTR_DATA;
txmsg.RTR = CAN_RTR_DATA;
txmsg.DLC = 8;
txmsg.data32[0] = 0x55AA55AA;
txmsg.data32[1] = 0x00FF00FF;
while (!chThdShouldTerminate()) {
canTransmit(&CAND1, CAN_ANY_MAILBOX, &txmsg, MS2ST(100));
chThdSleepMilliseconds(1000);
palTogglePad(GPIOE, GPIOE_LED3_RED);
}
return 0;
}
/*
* This is a periodic thread that does absolutely nothing except flashing LEDs.
*/
static WORKING_AREA(waThread1, 128);
static msg_t Thread1(void *arg) {
(void)arg;
chRegSetThreadName("blinker");
while (TRUE) {
//palSetPad(GPIOE, GPIOE_LED3_RED);
//chThdSleepMilliseconds(125);
//palClearPad(GPIOE, GPIOE_LED3_RED);
palSetPad(GPIOE, GPIOE_LED5_ORANGE);
chThdSleepMilliseconds(125);
palClearPad(GPIOE, GPIOE_LED5_ORANGE);
palSetPad(GPIOE, GPIOE_LED7_GREEN);
chThdSleepMilliseconds(125);
palClearPad(GPIOE, GPIOE_LED7_GREEN);
palSetPad(GPIOE, GPIOE_LED9_BLUE);
chThdSleepMilliseconds(125);
palClearPad(GPIOE, GPIOE_LED9_BLUE);
palSetPad(GPIOE, GPIOE_LED10_RED);
chThdSleepMilliseconds(125);
palClearPad(GPIOE, GPIOE_LED10_RED);
palSetPad(GPIOE, GPIOE_LED8_ORANGE);
chThdSleepMilliseconds(125);
palClearPad(GPIOE, GPIOE_LED8_ORANGE);
//palSetPad(GPIOE, GPIOE_LED6_GREEN);
//chThdSleepMilliseconds(125);
//palClearPad(GPIOE, GPIOE_LED6_GREEN);
//palSetPad(GPIOE, GPIOE_LED4_BLUE);
//chThdSleepMilliseconds(125);
//palClearPad(GPIOE, GPIOE_LED4_BLUE);
}
}
/*
* Application entry point.
*/
int main(void) {
/*
* System initializations.
* - HAL initialization, this also initializes the configured device drivers
* and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
*/
halInit();
chSysInit();
/*
* Activates the serial driver 1 using the driver default configuration.
* PA9(TX) and PA10(RX) are routed to USART1.
*/
sdStart(&SD1, NULL);
palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(7));
palSetPadMode(GPIOA, 10, PAL_MODE_ALTERNATE(7));
/*
* Activates the CAN driver 1.
*/
//Use PA11(CAN_RX) and PA12(CAN_TX)
palSetPadMode(GPIOA, 11, PAL_MODE_ALTERNATE(9) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_OPENDRAIN);
palSetPadMode(GPIOA, 12, PAL_MODE_ALTERNATE(9) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_OPENDRAIN);
canStart(&CAND1, &cancfg);
/*
* Starting the transmitter and receiver threads.
*/
chThdCreateStatic(can_rx_wa, sizeof(can_rx_wa), NORMALPRIO + 7, can_rx, NULL);
chThdCreateStatic(can_tx_wa, sizeof(can_tx_wa), NORMALPRIO + 7, can_tx, NULL);
/*
* Creates the example thread.
*/
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
/*
* Normal main() thread activity, in this demo it does nothing except
* sleeping in a loop and check the button state, when the button is
* pressed the test procedure is launched.
*/
while (TRUE) {
if (palReadPad(GPIOA, GPIOA_BUTTON))
palTogglePad(GPIOE, GPIOE_LED4_BLUE);
chThdSleepMilliseconds(500);
}
}