Skip to content

Instantly share code, notes, and snippets.

/stm32can.c Secret

Created July 21, 2016 21:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/69c3d9124c0a716162ebc795877af81c to your computer and use it in GitHub Desktop.
Save anonymous/69c3d9124c0a716162ebc795877af81c to your computer and use it in GitHub Desktop.
#include "defination.c"
#define REG_ACCESS(X) *((unsigned int *)X)
void can_init(int var)
{
//================================
if(var==1){
REG_ACCESS(RCC_APB1EN) |= (1<<25); // CAN 1 clock enable
REG_ACCESS(GPIOB_MODER) |= (2<<16)|(2<<18);
REG_ACCESS( GPIOB_OTYPER) =0x00000000;//???????????????????????????
// REG_ACCESS(GPIOB_OSPEEDR) |=
REG_ACCESS(GPIOB_PUPDR) |=0x00000000;
REG_ACCESS(GPIOB_AFRH) |= ((9<<1)|(9<<4)); // AF9 := 1001 for 8th and 9th pin
REG_ACCESS(CAN1_MCR) =(1<<0)|(1<<4); //Setting 0th bit INRQ and Setting 4th bit NART
while( !(REG_ACCESS(CAN1_MSR)&(0x01))); // Polling to chceck Oth bit is set or not
REG_ACCESS(CAN1_IER) =((1<<0)|(1<<2)); // enabling TMEIE and Enabling FFIE0
}else{
REG_ACCESS(RCC_APB1EN) |= (1<<26); // CAN 2 clock enable
REG_ACCESS(GPIOB_MODER) |= (2<<16)|(2<<18);
REG_ACCESS( GPIOB_OTYPER) =0x00000000;// for bit 5 and 6 ???????????????????????????
REG_ACCESS(GPIOB_PUPDR) |=0x00000000; //
REG_ACCESS(GPIOB_AFRL) |= ((9<<20)|(9<<24)); // AF9 := 1001 for 8th and 9th pin
REG_ACCESS(CAN1_MCR) =(1<<0)|(1<<4); //Setting 0th bit INRQ and Setting 4th bit NART
while( !(REG_ACCESS(CAN1_MSR)&(0x01))); // Polling to chceck Oth bit is set or not i.e checking 0th bit is set or not
REG_ACCESS(CAN1_IER) =((1<<0)|(1<<2)); // enabling TMEIE and Enabling FFIE0
} //end of else
//==============================
/* Note: this calculations fit for CAN (APB1) clock = 42MHz */
brp = (42000000 / 7) / 500000; /* baudrate is set to 500k bit/s */
/* set BTR register so that sample point is at about 71% bit time from bit start */
/* TSEG1 = 4, TSEG2 = 2, SJW = 3 => 1 CAN bit = 7 TQ, sample at 71% */
pCAN->BTR &= ~((( 0x03) << 24) | (( 0x07) << 20) | (( 0x0F) << 16) | ( 0x3FF));
pCAN->BTR |= ((((3-1) & 0x03) << 24) | (((2-1) & 0x07) << 20) | (((4-1) & 0x0F) << 16) | ((brp-1) & 0x3FF));
} // end of function
} // end of function
//======================================================================
void CAN_start(int var){
if(var==1){
REG_ACCESS(CAN1_MCR) &=~CAN_MCR_INRQ;
#ifndef __TEST
while (REG_ACCESS(CAN1_MSR) & CAN_MCR_INRQ);
#endif
}else{
REG_ACCESS(CAN2_MCR) &=~CAN_MCR_INRQ;
#ifndef __TEST
while (REG_ACCESS(CAN2_MSR) & CAN_MCR_INRQ);
#endif
}
} //end of can start
//==============================
/*----------------------------------------------------------------------------
set the testmode
----------------------------------------------------------------------------
void CAN_testmode (uint32_t ctrl, uint32_t testmode) {
CAN_TypeDef *pCAN = (ctrl == 1) ? CAN1 : CAN2;
pCAN->BTR &= ~(CAN_BTR_SILM | CAN_BTR_LBKM);
pCAN->BTR |= (testmode & (CAN_BTR_SILM | CAN_BTR_LBKM));
}
*/
//============================
void CAN_testmode (int var,int testmode) {
if(var==1){
REG_ACCESS(CAN1_BTR) &= ~(CAN_BTR_SILM | CAN_BTR_LBKM);
REG_ACCESS(CAN1_BTR) |= (testmode & (CAN_BTR_SILM | CAN_BTR_LBKM));
}else{
REG_ACCESS(CAN2_BTR) &= ~(CAN_BTR_SILM | CAN_BTR_LBKM);
REG_ACCESS(CAN2_BTR) |= (testmode & (CAN_BTR_SILM | CAN_BTR_LBKM));
}
}
//=============================
/*
/*----------------------------------------------------------------------------
check if transmit mailbox is empty
*----------------------------------------------------------------------------*/
//void CAN_waitReady (uint32_t ctrl) {
// CAN_TypeDef *pCAN = (ctrl == 1) ? CAN1 : CAN2;
//
// while ((pCAN->TSR & CAN_TSR_TME0) == 0); /* Transmit mailbox 0 is empty */
// CAN_TxRdy[ctrl-1] = 1;
//}
//===================================================
void check_tx_mailbox(int var){
if(var==1){
while((REG_ACCESS(CAN1_TSR) & CAN_TSR_TME0)==0); // if zero that means tx mailbox is empty
CAN_TxRdy[var-1] = 1; // CAN HARDWARE READY TO TRASNIT MSG
//uint32_t CAN_TxRdy[2] = {0,0}; /* CAN HW ready to transmit a message */
//uint32_t CAN_RxRdy[2] = {0,0}; /* CAN HW received a message */
}else{
while((REG_ACCESS(CAN1_TSR) & CAN_TSR_TME0)==0); // if zero that means tx mailbox is empty
CAN_TxRdy[var-1] = 1; // CAN HARRDWARE READY TO TRANSMIT MSG
//uint32_t CAN_TxRdy[2] = {0,0}; /* CAN HW ready to transmit a message */
//uint32_t CAN_RxRdy[2] = {0,0}; /* CAN HW received a message */
}
}
//===================================================
typedef struct {
unsigned int id; /* 29 bit identifier */
unsigned char data[8]; /* Data field */
unsigned char len; /* Length of data field in bytes */
unsigned char format; /* 0 - STANDARD, 1- EXTENDED IDENTIFIER */
unsigned char type; /* 0 - DATA FRAME, 1 - REMOTE FRAME */
} CAN_msg;
//====================================================
/*****************************************************************************************/
Write_msg_on_cntlr(int var ,CAN_msg *msg){
// I AM USING MAILBOX 0 ONLY
//CAN_wrMsg: Write a message to the CAN controller and transmit it.
if(var==1){
REG_ACCESS(CAN1_TI0R) = 0; /* reset TXRQ bit */ // CAN_TI 0 R <<zeroth mailbox
//Bit 0 TXRQ: Transmit mailbox request
// Set by software to request the transmission for the corresponding mailbox.
//Cleared by hardware when the mailbox becomes empty.
//-----------------------------------
if (msg->format == STANDARD_FORMAT) { /* Checking user selected standrard format or Extended */
REG_ACCESS(CAN1_TI0R) |= (msg->id << 21)| CAN_ID_STD;
}else {
REG_ACCESS(CAN1_TI0R) |= (msg->id << 3)| CAN_ID_EXT;
/*
The third bit of register TI0R if set to 1 ,means extented format and if 0 means standard format
CAN_ID_STD and CAN_ID_EXT macro is only used for setting or clearing third bit of TI0R register
*/
}
//------------------------------
if(msg->type == DATA_FRAME){
REG_ACCESS(CAN1_TI0R)|=CAN_RTR_DATA; // data frame selection
}
else{
REG_ACCESS(CAN1_TI0R)|=CAN_RTR_REMOTE; // setting 2nd bit 1 , to select RTR frame of TIOR register
}
//------------------------------
// CAN1 mailbox data low register CAN1_TDL0R four bytes of data put in this register byte 0 to byte 3
REG_ACCESS(CAN1_TDL0R) = ((msg->data[3] << 24) | (msg->data[2] << 16) | (msg->data[1] << 8) | (msg->data[0]));
// CAN1 mailbox data low register CAN1_TDH0R four bytes of data put in this register byte 4 to byte 7
REG_ACCESS(CAN1_TDH0R) = ((msg->data[7] << 24) | (msg->data[6] << 16) | (msg->data[5] << 8) | (msg->data[4]) );
//-----------------------------
/* CAN1_TDT0R CAN mailbox data length control and time stamp register
All bits of this register are write protected when the mailbox is not in empty state.
This field defines the number of data bytes a data frame contains or a remote frame request.
A message can contain from 0 to 8 data bytes, depending on the value in the DLC field.
*/
REG_ACCESS(CAN1_TDT0R) &= ~CAN_TDT0R_DLC; // setting to initially 0x00
REG_ACCESS(CAN1_TDT0R) |=(msg->len & CAN_TDT0R_DLC) // why Anding with CAN_TDT0R_DLC
REG_ACCESS(CAN1_IER) |=CAN_IER_TMEIE; // Transmit Mailbox Empty Interrupt Enable
REG_ACCESS(CAN1_TI0R)|=CAN_TI0R_TXRQ;
/*
Bit 0 TXRQ: Transmit mailbox request in TI0R Register
Set by software to request the transmission for the corresponding mailbox.
Cleared by hardware when the mailbox becomes empty.
*/
}
/***CAN2***/
else{
REG_ACCESS(CAN2_TI0R) = 0; /* reset TXRQ bit */ // CAN_TI 0 R <<zeroth mailbox
//Bit 0 TXRQ: Transmit mailbox request
// Set by software to request the transmission for the corresponding mailbox.
//Cleared by hardware when the mailbox becomes empty.
//-----------------------------------
if (msg->format == STANDARD_FORMAT) { /* Checking user selected standrard format or Extended */
REG_ACCESS(CAN2_TI0R) |= (msg->id << 21)| CAN_ID_STD;
}else {
REG_ACCESS(CAN2_TI0R) |= (msg->id << 3)| CAN_ID_EXT;
/*
The third bit of register TI0R if set to 1 ,means extented format and if 0 means standard format
CAN_ID_STD and CAN_ID_EXT macro is only used for setting or clearing third bit of TI0R register */
}
//------------------------------
if(msg->type == DATA_FRAME){
REG_ACCESS(CAN2_TI0R)|=CAN_RTR_DATA; // data frame selection
}else{
REG_ACCESS(CAN2_TI0R)|=CAN_RTR_REMOTE; // setting 2nd bit 1 , to select RTR frame of TIOR register
}
//------------------------------
// CAN2 mailbox data low register CAN2_TDL0R four bytes of data put in this register byte 0 to byte 3
REG_ACCESS(CAN2_TDL0R) = ((msg->data[3] << 24) | (msg->data[2] << 16) | (msg->data[1] << 8) | (msg->data[0]));
// CAN2 mailbox data low register CAN2_TDH0R four bytes of data put in this register byte 4 to byte 7
REG_ACCESS(CAN2_TDH0R) = ((msg->data[7] << 24) | (msg->data[6] << 16) | (msg->data[5] << 8) | (msg->data[4]) );
//-----------------------------
/* CAN2_TDT0R CAN mailbox data length control and time stamp register
All bits of this register are write protected when the mailbox is not in empty state.
This field defines the number of data bytes a data frame contains or a remote frame request.
A message can contain from 0 to 8 data bytes, depending on the value in the DLC field. */
REG_ACCESS(CAN2_TDT0R) &= ~CAN_TDT0R_DLC; // setting to initially 0x00
REG_ACCESS(CAN2_TDT0R) |=(msg->len & CAN_TDT0R_DLC) // why Anding with CAN_TDT0R_DLC
REG_ACCESS(CAN2_IER) |=CAN_IER_TMEIE; // Transmit Mailbox Empty Interrupt Enable
REG_ACCESS(CAN2_TI0R)|=CAN_TI0R_TXRQ;
/* Bit 0 TXRQ: Transmit mailbox request in TI0R Register
Set by software to request the transmission for the corresponding mailbox.
Cleared by hardware when the mailbox becomes empty. */
} } // end of write to controller function
/*----------------------------------------------------------------------------
setup acceptance filter
*----------------------------------------------------------------------------*/
void CAN_wrFilter(int var, int id, int format)
{
if(var==1){
//========================= FOR CAN1 FILTER CONFIG=====================
CAN1_filterIdx = 0; ///* static variable for the filter index */.
int CAN_msgId = 0;
//-------------------------
if (CAN1_filterIdx > 13) { /* check if Filter Memory is full*/
return;
}
//-------------------------
if (format == STANDARD_FORMAT) { /* Standard ID */
CAN_msgId |= (id << 21) | CAN_ID_STD;
}else { /* Extended ID */
CAN_msgId |= (id << 3) | CAN_ID_EXT;
}
//--------------------------
REG_ACCESS(CAN1_FMR) |= 1; /* set initMode for filter banks */
REG_ACCESS(CAN1_FA1R) &= ~(1<< CAN1_filterIdx); /* deactivate filter */
REG_ACCESS(CAN1_FS1R) |=(1 << CAN1_filterIdx); /* set 32-bit scale configuration */
REG_ACCESS(CAN1_FM1R) |= (1 << CAN1_filterIdx); /* set to 32-bit Identifier List mode */
REG_ACCESS(CAN1_FR1) = 0; //CAN_msgId; /* 32-bit identifier */
REG_ACCESS(CAN1_FR2)= CAN_msgId;
REG_ACCESS(CAN1_FFA1R) &= ~(1 << CAN1_filterIdx); /* assign filter to FIFO 0 */
REG_ACCESS(CAN1_FA1R) |= (1 << CAN1_filterIdx); /* activate filter */
REG_ACCESS(CAN1_FMR) |= ~1; /* reset initMode for filterBanks*/
CAN1_filterIdx++; /* increase filter index */
}//==============END OF CAN1 FILTER SETTING===========================
else{
//======== CAN2 FILTER CONFIG BEGINS HERE======================================
CAN2_filterIdx = 0; ///* static variable for the filter index */.
int CAN_msgId = 0;
//-------------------------
if (CAN2_filterIdx > 13) { /* check if Filter Memory is full*/
return;
}
//-------------------------
if (format == STANDARD_FORMAT) { /* Standard ID */
CAN_msgId |= (id << 21) | CAN_ID_STD;
}else { /* Extended ID */
CAN_msgId |= (id << 3) | CAN_ID_EXT;
}
//--------------------------
REG_ACCESS(CAN2_FMR) |= 1; /* set initMode for filter banks */
REG_ACCESS(CAN2_FA1R) &= ~(1<< CAN2_filterIdx); /* deactivate filter */
REG_ACCESS(CAN2_FS1R) |=(1 << CAN2_filterIdx); /* set 32-bit scale configuration */
REG_ACCESS(CAN2_FM1R) |= (1 << CAN2_filterIdx); /* set to 32-bit Identifier List mode */
REG_ACCESS(CAN2_FR1) = 0; //CAN_msgId; /* 32-bit identifier */
REG_ACCESS(CAN2_FR2)= CAN_msgId;
REG_ACCESS(CAN2_FFA1R) &= ~(1 << CAN2_filterIdx); /* assign filter to FIFO 0 */
REG_ACCESS(CAN2_FA1R) |= (1 << CAN2_filterIdx); /* activate filter */
REG_ACCESS(CAN2_FMR) |= ~1; /* reset initMode for filterBanks*/
CAN2_filterIdx++; /* increase filter index */
}
}
//============END OF FILTER FUNCTION======================
//=============READ MESSAGE FUNCTION==========================
void read_msg(int var,CAN_msg *msg){
if(var==1){ //CAN1 FIFO MAILBOX
// fifo 0 rir register
if(REG_ACCESS(CAN1_RI0R) & CAN_ID_EXT) == 0){
msg->format = STANDARD_FORMAT;
msg->id = 0x000007FF & (REG_ACCESS(CAN1_RI0R) >> 21); // why doing this *RESOLVED
}
else{
msg->format = EXTENDED_FORMAT;
msg->id = 0x1FFFFFFF & (REG_ACCESS(CAN1_RI0R) >> 3); // why doing this *RESOLVED
}
//====================
if(REG_ACCESS(CAN1_RI0R) & CAN_RTR_REMOTE) == 0){
msg->type = DATA_FRAME;
} else {
msg->type = REMOTE_FRAME;
}
//=====================
msg->len = REG_ACCESS(CAN1_RDT0R) & 0x0F; // GETTING LENGTH OF BYTES
msg->data[0] = REG_ACCESS(CAN1_RDL0R) & 0xFF;
msg->data[1] = (REG_ACCESS(CAN1_RDL0R)>>8) & 0xFF
msg->data[2] = (REG_ACCESS(CAN1_RDL0R)>>16)
msg->data[3] = (REG_ACCESS(CAN1_RDL0R) >>24)
msg->data[4] = REG_ACCESS(CAN1_RDH0R) & 0XFF
msg->data[5] = (REG_ACCESS(CAN1_RDH0R)>>8) & 0XFF
msg->data[6] = (REG_ACCESS(CAN1_RDH0R)>>16) & 0XFF
msg->data[7] = (REG_ACCESS(CAN1_RDH0R)>>24) & 0XFF
REG_ACCESS(CAN1_RF0R) |= CAN_RF0R_RFOM0; //Release FIFO 0 output mailbox
}
else{ // CAN2 FIFO MAILBOX
// fifo 0 rir register
if(REG_ACCESS(CAN2_RI0R) & CAN_ID_EXT) == 0){
msg->format = STANDARD_FORMAT;
msg->id = 0x000007FF & (REG_ACCESS(CAN2_RI0R) >> 21); // why doing this *RESOLVED
}
else{
msg->format = EXTENDED_FORMAT;
msg->id = 0x1FFFFFFF & (REG_ACCESS(CAN2_RI0R) >> 3); // why doing this *RESOLVED
}
//====================
if(REG_ACCESS(CAN2_RI0R) & CAN_RTR_REMOTE) == 0){
msg->type = DATA_FRAME;
} else {
msg->type = REMOTE_FRAME;
}
//=====================
msg->len = REG_ACCESS(CAN2_RDT0R) & 0x0F; // GETTING LENGTH OF BYTES
msg->data[0] = REG_ACCESS(CAN2_RDL0R) & 0xFF;
msg->data[1] = (REG_ACCESS(CAN2_RDL0R)>>8) & 0xFF
msg->data[2] = (REG_ACCESS(CAN2_RDL0R)>>16)
msg->data[3] = (REG_ACCESS(CAN2_RDL0R) >>24)
msg->data[4] = REG_ACCESS(CAN2_RDH0R) & 0XFF
msg->data[5] = (REG_ACCESS(CAN2_RDH0R)>>8) & 0XFF
msg->data[6] = (REG_ACCESS(CAN2_RDH0R)>>16) & 0XFF
msg->data[7] = (REG_ACCESS(CAN2_RDH0R)>>24) & 0XFF
REG_ACCESS(CAN2_RF0R) |= CAN_RF0R_RFOM0; //Release FIFO 0 output mailbox
}
}
//========================================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment