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