Loading...
Searching...
No Matches
can.c
1/***********************************************************************************
2 * @file can.c *
3 * @author Matt Ricci *
4 * @addtogroup CAN *
5 * @brief Brief description of the file's purpose. *
6 * *
7 * @todo Cleanup CAN interface header and implementation. *
8 ***********************************************************************************/
9
10#include "can.h"
11
17
18uint8_t CAN_RX(struct CAN_RX_data *CAN) {
19 if (CAN->CAN_number == 1) {
20 if (CAN1->RF1R & 0x3) { // checks to see if there was a CAN message recieved
21 CAN->address = (CAN1->sFIFOMailBox[1].RIR & 0xFFE00040) >> 21; // extracts the address from the CAN message and stores it into the CAN
22 CAN->dataL = CAN1->sFIFOMailBox[1].RDLR; // extracts the LSB 4 bytes
23 CAN->dataH = CAN1->sFIFOMailBox[1].RDHR; // extracts the MSB 4 bytes
24 CAN1->RF0R |= 1 << 5; // release FIFO
25 // clear bits 3 and 4 (indicating the mailboxes are full)
26 CAN1->RF0R &= (unsigned int)~(1 << 3);
27 CAN1->RF0R &= (unsigned int)~(1 << 4);
28 return 1;
29 } else
30 return 0; // returns 0 if nothing recieved
31 } else if (CAN->CAN_number == 2) { // samething but for CAN2
32 if (CAN2->RF1R & 0x3) {
33 CAN->address = (CAN2->sFIFOMailBox[1].RIR & 0xFFE00040) >> 21;
34 CAN->dataL = CAN2->sFIFOMailBox[1].RDLR;
35 CAN->dataH = CAN2->sFIFOMailBox[1].RDHR;
36 CAN2->RF1R |= 1 << 5;
37 // clear bits 3 and 4 (indicating the mailboxes are full)
38 CAN2->RF1R &= (unsigned int)~(1 << 3);
39 CAN2->RF1R &= (unsigned int)~(1 << 4);
40 return 1;
41 } else
42 return 0; // returns 0 if nothing recieved
43 } else
44 return 255;
45}
46
47uint8_t CAN_TX(uint8_t CAN, uint8_t data_length, unsigned int dataH, unsigned int dataL, unsigned int address) {
48 uint8_t mailbox = find_empty_CAN_TX_mailbox(CAN);
49 if (mailbox == 255)
50 return 250;
51 if (CAN == 1) {
52 CAN1->sTxMailBox[mailbox].TDHR = 0; // stores the dataH into the Mailbox to transmit
53 CAN1->sTxMailBox[mailbox].TDLR = 0; // stores the dataL into the Mailbox to transmit
54 CAN1->sTxMailBox[mailbox].TDTR = 0; // puts in the data length
55 CAN1->sTxMailBox[mailbox].TDHR = (unsigned int)dataH; // stores the dataH into the Mailbox to transmit
56 CAN1->sTxMailBox[mailbox].TDLR = (unsigned int)dataL; // stores the dataL into the Mailbox to transmit
57 CAN1->sTxMailBox[mailbox].TDTR = (unsigned int)data_length; // puts in the data length
58 // unsigned int CAN_TIR = CAN1->sTxMailBox[mailbox].TIR;
59 // CAN_TIR &= (unsigned int)~(0xFFE00000);
60 // CAN_TIR |= (uint8_t) (address << 21);// enters in the CAN identifer
61 CAN1->sTxMailBox[mailbox].TIR = 0;
62 CAN1->sTxMailBox[mailbox].TIR = (address << 21); // enters in the CAN identifer
63 // CAN1->sTxMailBox[mailbox].TIR |= CAN_TIR;
64 CAN1->sTxMailBox[mailbox].TIR |= (1 << 0); // requested transmission
65 while (1) // add timer in here for timeout
66 {
67 if ((CAN1->TSR & (1 << (1))))
68 return 0; // successful
69 else if ((CAN1->TSR & (1 << 3)))
70 CAN1->TSR |= (unsigned int)((1 << 7));
71 CAN1->TSR |= (unsigned int)((1 << 7)); // used to abort the transmissions if there is an error
72 return 1; // TX error
73 }
74 return 255; // timeout error
75 }
76 if (CAN == 2) {
77 CAN2->sTxMailBox[mailbox].TDHR = dataH;
78 CAN2->sTxMailBox[mailbox].TDLR = dataL;
79 CAN2->sTxMailBox[mailbox].TDTR = data_length;
80 CAN2->sTxMailBox[mailbox].TIR = address << 21;
81 CAN2->sTxMailBox[mailbox].TIR |= (1 << 0); // requested transmission
82 while (1) // add timer in here for timeout
83 {
84 if ((CAN2->TSR & (1 << (1))))
85 return 0; // successful
86 else if ((CAN2->TSR & (1 << 3))) {
87 CAN2->TSR |= (unsigned int)((1 << 7));
88 CAN2->TSR |= (unsigned int)((1 << 7));
89 return 1; // TX error
90 }
91 }
92 return 255; // timeout error
93 } else
94 return 100;
95}
96
97uint8_t find_empty_CAN_TX_mailbox(uint8_t CAN) {
98 return 0; // it is simply going to reload to the single mailbox and send
99 volatile uint32_t *CAN_address = &CAN1->TSR;
100 if (!((CAN == 1) || (CAN == 2)))
101 return 100;
102 if (CAN == 2) {
103 CAN_address = &CAN2->TSR;
104 }
105
106 for (uint8_t i = 0; i < 3; i++) {
107 if (*CAN_address & (1 << (i + 26))) {
108 return i; // returns the mailbox number
109 }
110 }
111 return 255; // if mailboxes are all full
112}
113
114void CANGPIO_config() {
115 // config AF functions
116 // CAN1 RX PA11 TXPA12 CAN2 RX PB12 TX PB13 both AF9
117 // Configure to Alternate Functions
118 GPIOA->MODER &= (uint32_t)~0x3C00000;
119 GPIOB->MODER &= (uint32_t)~0xF000000;
120 GPIOA->MODER |= 0x2800000;
121 GPIOB->MODER |= 0xA000000;
122 // Configure the TX to be push-pull
123 GPIOA->OTYPER &= (uint32_t)~0x1000;
124 GPIOB->OTYPER &= (uint32_t)~0x2000;
125 // Output speed
126 GPIOA->OSPEEDR |= 0x3000000;
127 GPIOB->OSPEEDR |= 0xC000000;
128 // set the pull-ups
129 GPIOA->PUPDR &= 0xC00000;
130 GPIOB->PUPDR &= 0x3000000;
131 // GPIOB->PUPDR |= 0x1000000;
132 // GPIOA->PUPDR |= 0x400000;
133 // Remap the AFIO
134 GPIOA->AFR[1] &= (uint32_t)~(0xFF000);
135 GPIOA->AFR[1] |= (0x99000);
136 GPIOB->AFR[1] &= (uint32_t)~(0xFF0000);
137 GPIOB->AFR[1] |= (0x990000);
138}
139
140void CAN_Peripheral_config() {
141 // volatile uint32_t* CAN = CAN1->MCR;
142 // for (uint8_t x = 0; x > 2; x++){
143 CAN1->MCR |= 0x8000; // reset CAN
144 while (((CAN1->MCR & (CAN_MCR_RESET)))); // wait until reset
145
146 CAN1->MCR |= 0x1;
147 while (!(CAN1->MSR & 1)); // change
148 CAN1->BTR &= (uint32_t)~(0xC37F03FF); // clears all bit timing bits and disables loop back and silent mode
149 CAN1->BTR |= 0x22B0014; // enters the Bitrate as 125kb/s
150 CAN1->MCR &= ~(CAN_MCR_SLEEP); // Clear sleep bit
151 CAN1->MCR &= (uint32_t)~(1 << 0); // places CAN into normal mode
152 while ((CAN1->MSR & (1 << 0))); // change for MSR
153
154 CAN1->FMR |= 0x1; // sets the filter initialisation to 'on'
155 CAN1->FM1R &= (uint32_t)~(0x1); // sets to mask mode filter
156 CAN1->FS1R |= 0x1; // sets to 32 bit mask, as the FR1/2 register is then for a single mask
157 CAN1->FFA1R |= 0x1; // Assigned to FIFO 1
158 CAN1->FS1R |= (1 << 25); // sets to 32 bit mask, as the FR1/2 register is then for a single mask
159 CAN1->FFA1R |= (1 << 25); // Assigned to FIFO 1
160 CAN1->FA1R &= 0xF0000000; // disable all filters
161 //
162 CAN1->sFilterRegister[0].FR1 = 0; // assign filters so it will filter nothing
163 CAN1->sFilterRegister[0].FR2 = 0;
164 CAN1->sFilterRegister[25].FR1 = 0; // assign filters so it will filter nothing
165 CAN1->sFilterRegister[25].FR2 = 0;
166
167 CAN1->FA1R |= 0x1; // enable the filter
168 CAN1->FA1R |= 1 << 25; // enable the filter
169 CAN1->FMR &= (uint32_t)~(0x1); // take out of initialisation mode
170
171 // this makes that all CAN messages will go to FIFO1
172 CAN2->MCR |= 0x8000; // reset CAN
173 while (((CAN2->MCR & (CAN_MCR_RESET)))); // wait until reset
174
175 CAN2->MCR |= 0x1;
176 while (!(CAN2->MSR & 1)); // change
177 CAN2->BTR &= (uint32_t)~(0xC37F03FF); // clears all bit timing bits and disables loop back and silent mode
178 CAN2->BTR |= 0x22B0014; // enters the Bitrate
179 CAN2->MCR &= ~(CAN_MCR_SLEEP); // Clear sleep bit
180 CAN2->MCR &= (uint32_t)~(1 << 0); // places CAN into normal mode
181 while ((CAN2->MSR & (1 << 0))); // change for MSR
182 CAN2->FMR &= (uint32_t)~(0x1); // take out of initialisation mode
183 CAN2->IER |= CAN_IER_FMPIE1;
184
185 // CAN2->FMR |= 0x1; // sets the filter initialisation to 'on'
186 // CAN2->FM1R &= (uint32_t)~(0x1); // sets to mask mode filter
187 // CAN2->FS1R |= (1 << 25); // sets to 32 bit mask, as the FR1/2 register is then for a single mask
188 // CAN2->FFA1R |= (1 << 25); // Assigned to FIFO 1
189 // CAN2->FA1R &= 0xF0000000; // disable all filters
190 // CAN2->sFilterRegister[0].FR1 = 0;// assign filters so it will filter nothing
191 // CAN2->sFilterRegister[0].FR2 = 0;
192 // CAN2->FA1R |= 0x1; // enable the filter
193
194 // this makes that all CAN messages will go to FIFO1
195}
#define CAN_MCR_RESET
#define CAN_IER_FMPIE1
#define CAN_MCR_SLEEP