We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello I'm trying to initialize the CAN controller on the DS80C400 but I cant set the bit SWINT (C0C.0) to 0 (so the CAN controller never starts up). I wrote some valid values to C0BT1 (TSEG1 and TSEG2 other than zero). C0BT1 is locatet at the CAN data memory (and if the values TSEG1 and/or TSEG2 are zero --> SWINT will never go to 0). Now I suppose that I write the wrong memory location (access problem ? I use FVAR to acces the CAN data mem). Here's the c-code from my initCAN routine:
void initCAN() { printf("DEBUG_0: C0C: %bx \r\n", C0C); printf("DEBUG_1: C0S: %bx \r\n", C0S); while((C0C&0x08)==0x08) //while CRST == 1 (I don't know why, but if I dont do this (just try one time)--> CRST wont go to 0 { TA = 0xAA; //get write access to protected bits.. TA = 0x55; //..got acces for 3 machine cycles C0C = 0x01; //set software initialisation bit (SWINT = 1 --> disable CAN Controller) } printf("DEBUG_3: C0C: %bx \r\n", C0C); P5CNT |= 0x08; //P5CNT.3 =1; enable CAN0 pins 5.0 / 5.1 printf("DEBUG_5: C0C: %bx \r\n", C0C); //baudrate TSEG ... //set C0BT0 = 0x42; FVAR(unsigned char, 0xFFDB04) = 0x42; //SJW1-0 = 1; BPR5-0 = 0x02 printf("DEBUG_6: C0BT0: %bx \r\n", FVAR(unsigned char, 0xFFDB04)); printf("DEBUG_7: C0BT0_adr: %lx \r\n", &FVAR(unsigned char, 0xFFDB04)); // not shure if this works.. COR &= 0xE7; //C0BPR7-6 = 0; (Prescaler C0BPR0-7 is set to 2) //set C0BT0 = 0x56; FVAR(unsigned char, 0xFFDB05) = 0x56; //TSEG1 = 6, TSEG2 =5, SMP = 0 -->0x56 printf("DEBUG_8: C0BT1: %bx \r\n", FVAR(unsigned char, 0xFFDB05)); printf("DEBUG_9: C0BT1_adr: %lx \r\n", &FVAR(unsigned char, 0xFFDB05)); // not shure if this works.. //DBYTE[0xFFDB00+4] = 0x42; //reg C0BT0: BR Prescaler = 2; SJW1-0 = 1; printf("DEBUG_10: C0C: %bx \r\n", C0C); //enable message center 1 //register C0M1AR0 - C0M1AR3 FVAR(unsigned char, 0xFFDB12) = 0x00; //Extended ID = 0.. FVAR(unsigned char, 0xFFDB13) = 0x00; //.. FVAR(unsigned char, 0xFFDB14) = 0x00; //.. FVAR(unsigned char, 0xFFDB15) = 0x00; //.. + WTOE = 0; (no overwrite enable on recieve) //register C0M1F FVAR(unsigned char, 0xFFDB16) = 0x88; // 8 databytes, transmit, 11bit id, no message identification mask (recv.), // no media identification mask //enable interrups EA = 1; C0IE = 1; C0M1C = 0xC1; //message center 1 ready, enable transmit interrupt TA = 0xAA; //get write access to protected bits.. TA = 0x55; //..got acces for 3 machine cycles C0C = 0x00; //clear software initialisation bit (SWINT = 0 --> enable CAN Controller) printf("DEBUG_11: C0C: %bx \r\n", C0C); }
first thanks for the feedback -As far as I know, the SWINT bit is also timed access (DS80C400UG.pdf, page 33 --> reg. C0C-"bit-map" SWINT is RT). Anyway, I took the timed acces on the SWINT away and also the while(..){...} loop but the result is still the same. I wonder if I missed(/don't know about) some essential settings... -What do you think about the mem access (far) and the mem settings? I'm not shure about this but I think it should work.. thanks
I was looking at the DS390, not the DS400 manual --- so maybe they did make SWINT TA from one to the other. Be sure you check back the errata sheets about this, though --- it could still be a documentation misprint. As to the while loop: you should keep the loop. Just don't re-do the write to C0C in every iteration. This is a register bit with some complicated logics sitting on the other side of it --- writing to it may take some time to propagate, and every time you write, that time would start anew. As to the RAM layout: no, I don't think that's correct. The RAM layout definition makes the compiler think there is normal XRAM up there, to be used for ordinary variables. I'm quite sure that's not what you want. This would be different if you had used fixed-address variables to map those CAN registers, instead of using the FVAR macro.
As to the RAM layout: no, I don't think that's correct. The RAM layout definition makes the compiler think there is normal XRAM up there, to be used for ordinary variables. I'm quite sure that's not what you want. This would be different if you had used fixed-address variables to map those CAN registers, instead of using the FVAR macro. So, does this mean I never write to the CAN mem ? If so, then SWINT can't be set to 0 because I would never set TSEG1/2 to valid values (!=0). But I don't know how to tell the compiler that there is CAN memory...
So, does this mean I never write to the CAN mem ? No. It could mean that the compiler places ordinary variables in the CAN XRAM register area. You don't want that. If so, then SWINT can't be set to 0 because I would never set TSEG1/2 to valid values (!=0). But I don't know how to tell the compiler that there is CAN memory... As long as you're using the FVAR() macro, I don't think there's any reason at all to tell the compiler about the presence of that CAN XRAM register bank. The compiler doesn't have to know it, so there's no harm done if you don't tell it. I think what you should do now is: 1) try this code in the simulator. Open the CAN periphal viewer and see how the register contents change (or don't...). 2) remove the XRAM mapping for the CAN registers, or at least check the map file to make sure that no variables were located there.
remove the XRAM mapping for the CAN registers, or at least check the map file to make sure that no variables were located there. I did remove the XRAM mapping (0xFFDB00..) try this code in the simulator. Open the CAN periphal viewer and see how the register contents change (or don't...). Ok this may take a while because I've got some problems using the simulator (Simulation starts at adr 0x000000 but my code starts at 0x400000. If i set the pc to 0x400000, then my program jumps out to somwhere it shouldn't on the first LCALL ... access violation...and so on) I write back if this works
Ok I'm now able to run mon400 on the TINIm400 and debug the program on the target system. So, I stepped through the initCAN() and as supposed: The registers C0BT0 and C0BT1 (and all the other registers in the CAN ram) are never written. I.e. no change on register C0BT0 at the command:
FVAR(unsigned char, 0xFFDB04) = 0x42;
I.e. no change on register C0BT0 at the command:
Hi you didn't actually manage to set CMA=1. CMA was 1 all the time, I verified this in the startup code and with the debugger... But anyway, I've got the CAN-controller running now. While debugging, I noticed that r/w from/to absolute addresses above 0x7FFFFF doesn't work. So I did set CMA to 0 (CAN mem now @ 0x00DBxx) and access the mem like this:
unsigned char far *can; ... //set C0BT0 = 0x42; can = &FVAR(unsigned char, 0x00DB04); *can = 0x42;