├── Hardware ├── J3068 LIN EVSE and EV (EV Config).csv ├── J3068 LIN EVSE and EV (EVB Config).csv ├── J3068 LIN EVSE and EV (SE Config).csv ├── J3068 LIN EVSE and EV (SEB Config).csv ├── J3068 LIN EVSE and EV.pcb ├── J3068 LIN EVSE and EV.pdf └── J3068 LIN EVSE and EV.sch ├── Info Codes.ods ├── J3068-2.ldf ├── LICENSE ├── LIN_4_6_5_add_mc9s12g.patch ├── Project ├── .clang-format ├── C_Layout.hwl ├── Default.mem ├── P&E_Multilink_USB.ini ├── Project.mcp ├── Project_Data │ ├── CWSettingsWindows.stg │ ├── S12X │ │ └── TargetDataWindows.tdt │ └── Standard │ │ └── TargetDataWindows.tdt ├── Sources │ ├── InfoCodeStrings.h │ ├── Start12.c │ ├── adc_constants.h │ ├── canbus.c │ ├── canbus.h │ ├── config.h │ ├── datapage.c │ ├── derivative.h │ ├── evse_smarts.c │ ├── evse_smarts.h │ ├── globals.c │ ├── globals.h │ ├── hardware.c │ ├── hardware.h │ ├── ids_handler.c │ ├── ids_handler.h │ ├── info_code_handler.c │ ├── info_code_handler.h │ ├── info_codes.h │ ├── interrupts.c │ ├── j1939-signals.c │ ├── j1939-signals.h │ ├── j1939.c │ ├── j1939.h │ ├── j3072_handler.c │ ├── j3072_handler.h │ ├── lin-cp.c │ ├── lin-cp.h │ ├── lock.c │ ├── lock.h │ ├── main.c │ ├── pilot.c │ ├── pilot.h │ ├── protocol_version_handler.c │ ├── protocol_version_handler.h │ ├── scheduler.c │ ├── scheduler.h │ ├── sci.c │ ├── sci.h │ ├── serialCmds.c │ ├── serialCmds.h │ ├── string_utils.c │ ├── string_utils.h │ ├── timers.h │ ├── types.h │ ├── utils.c │ └── utils.h ├── USBDM.ini ├── lin_cfg │ ├── lin_cfg.c │ ├── lin_cfg.h │ ├── lin_cfg_ev.c │ ├── lin_cfg_ev.h │ ├── lin_cfg_evse.c │ ├── lin_cfg_evse.h │ └── lin_hw_cfg.h └── prm │ ├── Project.prm │ ├── S12X.bbl │ ├── S12X.prm │ └── burner.bbl ├── README.md ├── S12G-dual-master.npf ├── S12G-dual-slave.npf └── adc_constants.m /Hardware/J3068 LIN EVSE and EV (EV Config).csv: -------------------------------------------------------------------------------- 1 | ****Variant: EV****, 2 | Manufacturer,Manufacturer Part Number,Distributor,Distributor Part Number,Part,Value,Qty,Name, 3 | ,,,,C805,8p,2,C14 C15, 4 | Samsung,CL10B105KO8NNNC,Digikey,1276-1019-2-ND,C603,1u,2,C19 C27, 5 | ,CL10B104KO8NNWC,,,C603,100n,3,C20 C28 C30, 6 | Samsung,CL21A226MOCLRNC,,,C805,22u,1,C22, 7 | Murata,NFM21PC105B1C3D,Digikey,490-3912-2-ND,NFM21P,INST,2,C23 C24, 8 | Panasonic,RL81C221MDN1KX,Digikey,P16296-ND,16SEPC220MD,220u,1,C29, 9 | Samsung,C0603C223K5RACTU,,,C603,220n,4,C43 C47 C48 C49, 10 | Kemet,C0603C472K5RACTU,,,C603,4.7n,1,C46, 11 | ,BHR-14-VUA,,,14pin_conn_vert,INST,1,CONN1, 12 | ,BHR-12-VUA,,,12pin_conn_vert,INST,1,CONN2, 13 | Rohm Semiconductor,RB496EATR,,,RB496EATR,INST,1,D4, 14 | Diodes/Zetex,ZHCS400TA,Digikey,ZHCS400TR-ND,ZHCS400,INST,1,DS1A, 15 | Belfuse,0ZCG0150BF2C,Digikey,507-1773-2-ND,0ZCC,40 mOhms,1,F1, 16 | Littelfuse Inc.,PICOASMDC010S-2,Digikey,507-1516-2-ND,Fuse805,INST,2,F7 F8, 17 | ,,,,CONN2,,3,GND1 GND2 GND3, 18 | Microchip Technology,MCP6561T-E/LT,Digikey,,MCP6561T-E_LT,INST,1,IC1, 19 | ,LV8548MC-AH,,,LV8548MC-AH,INST,1,IC2, 20 | ,MC78M05BDTRKG,,,MC78M05BDTRKG,INST,1,IC3, 21 | 3M,961206-6404-AR,Digikey,,BDM_no_shroud,INST,1,J1, 22 | Murata,BLM21PG221SN1D,Digikey,490-1054-2-ND,BLM21P,INST,1,L3, 23 | Lite-On,LTST-C190KRKT,,,LED603,INST,1,LED3, 24 | ,NXV75UPR,,,PMOS SOT23,INST,1,Q1, 25 | Stackpole Electronics Inc,CSRN2010FKR500,,,CSRN2010,0.5,2,R5 R6, 26 | Yageo,AT0603BRD0710KL,,,R603,10k,4,R9 R10 R11 R23, 27 | ,RMCF0603FT8K20,,,R603,8.2k,1,R13, 28 | Vishay Dale,CRCW06031K00FKEAC,,,R603,1k,5,R26 R57 R58 R63 R90, 29 | ,RMCF0603FT33K0,,,R603,36k,1,R28, 30 | Yageo,RC0603JR-070RL,,,R603,0,7,R29 R30 R36 R42 R44 R70 R72, 31 | Yageo,RC0603JR-07200RL,,,R603,200,4,R31 R32 R33 R34, 32 | Yageo,RC0603FR-0791KL,,,R603,91k,1,R37, 33 | Yageo,RC0603FR-0762KL,,,R603,62k,1,R38, 34 | Yageo,RMCF0603JT200K,,,R603,200k,1,R39, 35 | Yageo,RT0603DRE0710KL,,,R603,10k,5,R40 R61 R62 R76 R78, 36 | Stackpole Electronics Inc.,RC1608F133CS,,,R603,13k,1,R41, 37 | ,RMCF0603JT120R,,,R603,120,1,R89, 38 | ,,,,R1206,1400,1,RS2A, 39 | ,,,,R1206,3000,1,RS3A, 40 | ,,,,R1206,330,1,RS4A, 41 | ,DMN32D2LDF-7,,,DMN32D2LDF,INST,1,SS2A, 42 | Allegro,A4954ELPTR-T,Digikey,620-1384-1-ND,A4954ELPTR-T,INST,1,U3, 43 | Diodes Inc.,DT1042-04SO-7,Digikey,DT1042-04SO-7DICT-ND,HDMIULC6-4SC6,INST,4,U8 U15 U16 U17, 44 | STMicroelectronics,ETP01-2821,Digikey,497-8909-6-ND,ETP01-2821,INST,1,U9, 45 | TI,SN65HVDA100QDRQ1,,,TI_LIN_SN65HVDA100-Q1,INST,1,U22, 46 | STMicroelectronics,ST715MR,,,ST715,INST,1,U23, 47 | TI,SN65HVD1040DR,Digikey,,SND65HVD230,INST,1,U30, 48 | NXP,S9S12G96F0CLH,,,S12G96 64-pin,INST,1,U32, 49 | FCI,67997-400HLF,,,Jumper,INST,1,U33, 50 | Raltron Electronics,RH100-12.000-8-EXT-TR,,,XTAL-Can,,1,XTAL1, 51 | End of Regular BOM, 52 | DNI List:,C1 C[2-3] C4 C5 C6 C44 C45 D[1-3] DS2A D[6-7] F[9-10] IC5 L[1-2] LED4 LED6 LED5 LED7 R1 R2 R35 R3 R4 R12 R14 R75 RS5A RS5B R24 R[64-67] R43 R[45-46] R49 R71 R54 R55 R56 RS1*A RS1*B RS1A RS1B R60 R79 RS[2-4]B SS2B SW[1-2] U1 U21 U24, 53 | Board info:, 54 | Board size in mils: 0 x 0 and board size in mm: 0.00 x 0.00, 55 | Parts Counts-> Total_Parts: 83 SM: 0 TH: 83 Unique_Parts: 48 SM: 0 TH: 48, 56 | Counts-> SM-pads: 0 TH-pins: 329, 57 | -------------------------------------------------------------------------------- /Hardware/J3068 LIN EVSE and EV (EVB Config).csv: -------------------------------------------------------------------------------- 1 | ****Variant: EVB****, 2 | Manufacturer,Manufacturer Part Number,Distributor,Distributor Part Number,Part,Value,Qty,Name, 3 | ,,,,C805,8p,2,C14 C15, 4 | Samsung,CL10B105KO8NNNC,Digikey,1276-1019-2-ND,C603,1u,2,C19 C27, 5 | ,CL10B104KO8NNWC,,,C603,100n,3,C20 C28 C30, 6 | Samsung,CL21A226MOCLRNC,,,C805,22u,1,C22, 7 | Murata,NFM21PC105B1C3D,Digikey,490-3912-2-ND,NFM21P,INST,2,C23 C24, 8 | Panasonic,RL81C221MDN1KX,Digikey,P16296-ND,16SEPC220MD,220u,1,C29, 9 | Samsung,C0603C223K5RACTU,,,C603,220n,4,C43 C47 C48 C49, 10 | Kemet,C0603C472K5RACTU,,,C603,4.7n,2,C45 C46, 11 | ,BHR-14-VUA,,,14pin_conn_vert,INST,1,CONN1, 12 | ,BHR-12-VUA,,,12pin_conn_vert,INST,1,CONN2, 13 | Rohm Semiconductor,RB496EATR,,,RB496EATR,INST,1,D4, 14 | Diodes/Zetex,ZHCS400TA,Digikey,ZHCS400TR-ND,ZHCS400,INST,2,DS1A DS2A, 15 | Belfuse,0ZCG0150BF2C,Digikey,507-1773-2-ND,0ZCC,40 mOhms,1,F1, 16 | Littelfuse Inc.,PICOASMDC010S-2,Digikey,507-1516-2-ND,Fuse805,INST,4,F7 F8 F9 F10, 17 | ,,,,CONN2,,3,GND1 GND2 GND3, 18 | Microchip Technology,MCP6561T-E/LT,Digikey,,MCP6561T-E_LT,INST,2,IC1 IC5, 19 | ,LV8548MC-AH,,,LV8548MC-AH,INST,1,IC2, 20 | ,MC78M05BDTRKG,,,MC78M05BDTRKG,INST,1,IC3, 21 | 3M,961206-6404-AR,Digikey,,BDM_no_shroud,INST,1,J1, 22 | Murata,BLM21PG221SN1D,Digikey,490-1054-2-ND,BLM21P,INST,1,L3, 23 | Lite-On,LTST-C190KRKT,,,LED603,INST,1,LED3, 24 | ,NXV75UPR,,,PMOS SOT23,INST,1,Q1, 25 | Stackpole Electronics Inc,CSRN2010FKR500,,,CSRN2010,0.5,2,R5 R6, 26 | Yageo,AT0603BRD0710KL,,,R603,10k,4,R9 R10 R11 R23, 27 | ,RMCF0603FT8K20,,,R603,8.2k,1,R13, 28 | Vishay Dale,CRCW06031K00FKEAC,,,R603,1k,6,R24 R26 R57 R58 R63 R90, 29 | ,RMCF0603FT33K0,,,R603,36k,1,R28, 30 | Yageo,RC0603JR-070RL,,,R603,0,9,R29 R30 R36 R42 R44 R46 R70 R71 R72, 31 | Yageo,RC0603JR-07200RL,,,R603,200,4,R31 R32 R33 R34, 32 | Yageo,RC0603FR-0791KL,,,R603,91k,2,R37 R55, 33 | Yageo,RC0603FR-0762KL,,,R603,62k,2,R38 R54, 34 | Yageo,RMCF0603JT200K,,,R603,200k,2,R39 R60, 35 | Yageo,RT0603DRE0710KL,,,R603,10k,6,R40 R61 R62 R76 R78 R79, 36 | Stackpole Electronics Inc.,RC1608F133CS,,,R603,13k,1,R41, 37 | ,RMCF0603JT120R,,,R603,120,1,R89, 38 | ,,,,R1206,1400,1,RS2A, 39 | ,,,,R1206,3000,3,RS2B RS3A RS3B, 40 | ,,,,R1206,330,2,RS4A RS4B, 41 | ,DMN32D2LDF-7,,,DMN32D2LDF,INST,2,SS2A SS2B, 42 | Allegro,A4954ELPTR-T,Digikey,620-1384-1-ND,A4954ELPTR-T,INST,1,U3, 43 | Diodes Inc.,DT1042-04SO-7,Digikey,DT1042-04SO-7DICT-ND,HDMIULC6-4SC6,INST,4,U8 U15 U16 U17, 44 | STMicroelectronics,ETP01-2821,Digikey,497-8909-6-ND,ETP01-2821,INST,2,U9 U21, 45 | TI,SN65HVDA100QDRQ1,,,TI_LIN_SN65HVDA100-Q1,INST,2,U22 U24, 46 | STMicroelectronics,ST715MR,,,ST715,INST,1,U23, 47 | TI,SN65HVD1040DR,Digikey,,SND65HVD230,INST,1,U30, 48 | NXP,S9S12G96F0CLH,,,S12G96 64-pin,INST,1,U32, 49 | FCI,67997-400HLF,,,Jumper,INST,1,U33, 50 | Raltron Electronics,RH100-12.000-8-EXT-TR,,,XTAL-Can,,1,XTAL1, 51 | End of Regular BOM, 52 | DNI List:,C1 C[2-3] C4 C5 C6 C44 D[1-3] D[6-7] L[1-2] LED4 LED6 LED5 LED7 R1 R2 R35 R3 R4 R12 R14 R75 RS5A RS5B R43 R45 R49 R56 RS1*A RS1*B RS1A RS1B R[64-67] SW[1-2] U1, 53 | Board info:, 54 | Board size in mils: 0 x 0 and board size in mm: 0.00 x 0.00, 55 | Parts Counts-> Total_Parts: 101 SM: 0 TH: 101 Unique_Parts: 48 SM: 0 TH: 48, 56 | Counts-> SM-pads: 0 TH-pins: 383, 57 | -------------------------------------------------------------------------------- /Hardware/J3068 LIN EVSE and EV (SE Config).csv: -------------------------------------------------------------------------------- 1 | ****Variant: SE****, 2 | Manufacturer,Manufacturer Part Number,Distributor,Distributor Part Number,Part,Value,Qty,Name, 3 | Taiyo Yuden,EMK316B7475KL-T,,,C1206,4.7u,1,C1, 4 | Samsung,CL21A226MOCLRNC,,,C805,22u,3,C2 C3 C22, 5 | AVX,08051A4R7CAT2A,,,C805,4.7p,1,C4, 6 | ,CL10B104KO8NNWC,,,C603,100n,4,C5 C20 C28 C30, 7 | Kemet,C0805C101J5GAC7800,,,C805,100p,1,C6, 8 | ,,,,C805,8p,2,C14 C15, 9 | Samsung,CL10B105KO8NNNC,Digikey,1276-1019-2-ND,C603,1u,3,C19 C27 C44, 10 | Murata,NFM21PC105B1C3D,Digikey,490-3912-2-ND,NFM21P,INST,2,C23 C24, 11 | Panasonic,RL81C221MDN1KX,Digikey,P16296-ND,16SEPC220MD,220u,1,C29, 12 | Samsung,C0603C223K5RACTU,,,C603,220n,4,C43 C47 C48 C49, 13 | Kemet,C0603C472K5RACTU,,,C603,4.7n,1,C46, 14 | ,BHR-14-VUA,,,14pin_conn_vert,INST,1,CONN1, 15 | Diodes/Zetex,ZHCS400TA,Digikey,ZHCS400TR-ND,ZHCS400,INST,3,D1 D2 D3, 16 | Rohm Semiconductor,RB496EATR,,,RB496EATR,INST,1,D4, 17 | Fairchild,MM5Z15V,Digikey,MM5Z15VTR-ND,MM5Z15V,INST,2,D6 D7, 18 | Belfuse,0ZCG0150BF2C,Digikey,507-1773-2-ND,0ZCC,40 mOhms,1,F1, 19 | Littelfuse Inc.,PICOASMDC010S-2,Digikey,507-1516-2-ND,Fuse805,INST,2,F7 F8, 20 | ,,,,CONN2,,3,GND1 GND2 GND3, 21 | Microchip Technology,MCP6561T-E/LT,Digikey,,MCP6561T-E_LT,INST,1,IC1, 22 | ,MC78M05BDTRKG,,,MC78M05BDTRKG,INST,1,IC3, 23 | 3M,961206-6404-AR,Digikey,,BDM_no_shroud,INST,1,J1, 24 | Murata,LQH44PN100MP0L,Digikey,490-5330-2-ND,LQH44P,10uH,2,L1 L2, 25 | Murata,BLM21PG221SN1D,Digikey,490-1054-2-ND,BLM21P,INST,1,L3, 26 | Lite-On,LTST-C190KRKT,,,LED603,INST,2,LED3 LED5, 27 | Lite-On,LTST-C190KGKT,,,LED603,INST,1,LED4, 28 | ,NXV75UPR,,,PMOS SOT23,INST,1,Q1, 29 | Panasonic Electronic Components,ERJ6ENF9093V,,,R805,909k,1,R1, 30 | Yageo,RT0603DRD07100KL,,,R603,100k,2,R2 R35, 31 | Yageo,RC0805FR-07137KL,,,R805,137k,1,R3, 32 | Panasonic Electronic Components,ERJ6ENF1004V,,,R805,1meg,1,R4, 33 | ,RMCF0603FT8K20,,,R603,8.2k,1,R13, 34 | Vishay Dale,CRCW06031K00FKEAC,,,R603,1k,7,R26 R57 R58 R63 R64 R65 R90, 35 | ,RMCF0603FT33K0,,,R603,36k,1,R28, 36 | Yageo,RC0603FR-0791KL,,,R603,91k,1,R37, 37 | Yageo,RC0603FR-0762KL,,,R603,62k,1,R38, 38 | Yageo,RMCF0603JT200K,,,R603,200k,1,R39, 39 | Yageo,RT0603DRE0710KL,,,R603,10k,3,R40 R61 R62, 40 | Stackpole Electronics Inc.,RC1608F133CS,,,R603,13k,1,R41, 41 | Yageo,RC0603JR-070RL,,,R603,0,3,R43 R49 R70, 42 | Yageo,RC1206FR-07976RL,,,R1206,976,2,RS1*A RS1A, 43 | ,,,,R1206,330,1,RS4A, 44 | ,DG470EQ-T1-E3,,,DG419L-umax,INST,1,SW1, 45 | Linear,LT1945EMS,Digikey,LT1945EMS#TRPBF-ND,LT1945,INST,1,U1, 46 | Diodes Inc.,DT1042-04SO-7,Digikey,DT1042-04SO-7DICT-ND,HDMIULC6-4SC6,INST,3,U8 U15 U16, 47 | STMicroelectronics,ETP01-2821,Digikey,497-8909-6-ND,ETP01-2821,INST,1,U9, 48 | TI,SN65HVDA100QDRQ1,,,TI_LIN_SN65HVDA100-Q1,INST,1,U22, 49 | STMicroelectronics,ST715MR,,,ST715,INST,1,U23, 50 | NXP,S9S12G96F0CLH,,,S12G96 64-pin,INST,1,U32, 51 | Raltron Electronics,RH100-12.000-8-EXT-TR,,,XTAL-Can,,1,XTAL1, 52 | End of Regular BOM, 53 | DNI List:,C45 CONN2 DS[1-2]A F[9-10] IC2 IC5 LED6 LED7 R[5-6] R[9-11] R23 R12 R14 R75 RS5A RS5B R24 R[66-67] R[29-30] R36 R42 R[44-46] R[71-72] R[31-34] R54 R55 R56 RS1*B RS1B R60 R76 R[78-79] R89 RS2A RS2B RS3A RS[3-4]B SS2A SS2B SW2 U3 U17 U21 U24 U30 U33, 54 | Board info:, 55 | Board size in mils: 0 x 0 and board size in mm: 0.00 x 0.00, 56 | Parts Counts-> Total_Parts: 83 SM: 0 TH: 83 Unique_Parts: 49 SM: 0 TH: 49, 57 | Counts-> SM-pads: 0 TH-pins: 298, 58 | -------------------------------------------------------------------------------- /Hardware/J3068 LIN EVSE and EV (SEB Config).csv: -------------------------------------------------------------------------------- 1 | ****Variant: SEB****, 2 | Manufacturer,Manufacturer Part Number,Distributor,Distributor Part Number,Part,Value,Qty,Name, 3 | Taiyo Yuden,EMK316B7475KL-T,,,C1206,4.7u,1,C1, 4 | Samsung,CL21A226MOCLRNC,,,C805,22u,3,C2 C3 C22, 5 | AVX,08051A4R7CAT2A,,,C805,4.7p,1,C4, 6 | ,CL10B104KO8NNWC,,,C603,100n,4,C5 C20 C28 C30, 7 | Kemet,C0805C101J5GAC7800,,,C805,100p,1,C6, 8 | ,,,,C805,8p,2,C14 C15, 9 | Samsung,CL10B105KO8NNNC,Digikey,1276-1019-2-ND,C603,1u,3,C19 C27 C44, 10 | Murata,NFM21PC105B1C3D,Digikey,490-3912-2-ND,NFM21P,INST,2,C23 C24, 11 | Panasonic,RL81C221MDN1KX,Digikey,P16296-ND,16SEPC220MD,220u,1,C29, 12 | Samsung,C0603C223K5RACTU,,,C603,220n,4,C43 C47 C48 C49, 13 | Kemet,C0603C472K5RACTU,,,C603,4.7n,2,C45 C46, 14 | ,BHR-14-VUA,,,14pin_conn_vert,INST,1,CONN1, 15 | Diodes/Zetex,ZHCS400TA,Digikey,ZHCS400TR-ND,ZHCS400,INST,3,D1 D2 D3, 16 | Rohm Semiconductor,RB496EATR,,,RB496EATR,INST,1,D4, 17 | Fairchild,MM5Z15V,Digikey,MM5Z15VTR-ND,MM5Z15V,INST,2,D6 D7, 18 | Belfuse,0ZCG0150BF2C,Digikey,507-1773-2-ND,0ZCC,40 mOhms,1,F1, 19 | Littelfuse Inc.,PICOASMDC010S-2,Digikey,507-1516-2-ND,Fuse805,INST,4,F7 F8 F9 F10, 20 | ,,,,CONN2,,3,GND1 GND2 GND3, 21 | Microchip Technology,MCP6561T-E/LT,Digikey,,MCP6561T-E_LT,INST,2,IC1 IC5, 22 | ,MC78M05BDTRKG,,,MC78M05BDTRKG,INST,1,IC3, 23 | 3M,961206-6404-AR,Digikey,,BDM_no_shroud,INST,1,J1, 24 | Murata,LQH44PN100MP0L,Digikey,490-5330-2-ND,LQH44P,10uH,2,L1 L2, 25 | Murata,BLM21PG221SN1D,Digikey,490-1054-2-ND,BLM21P,INST,1,L3, 26 | Lite-On,LTST-C190KRKT,,,LED603,INST,3,LED3 LED5 LED7, 27 | Lite-On,LTST-C190KGKT,,,LED603,INST,2,LED4 LED6, 28 | ,NXV75UPR,,,PMOS SOT23,INST,1,Q1, 29 | Panasonic Electronic Components,ERJ6ENF9093V,,,R805,909k,1,R1, 30 | Yageo,RT0603DRD07100KL,,,R603,100k,2,R2 R35, 31 | Yageo,RC0805FR-07137KL,,,R805,137k,1,R3, 32 | Panasonic Electronic Components,ERJ6ENF1004V,,,R805,1meg,1,R4, 33 | ,RMCF0603FT8K20,,,R603,8.2k,1,R13, 34 | Vishay Dale,CRCW06031K00FKEAC,,,R603,1k,10,R24 R26 R57 R58 R63 R64 R65 R66 R67 R90, 35 | ,RMCF0603FT33K0,,,R603,36k,1,R28, 36 | Yageo,RC0603FR-0791KL,,,R603,91k,2,R37 R55, 37 | Yageo,RC0603FR-0762KL,,,R603,62k,2,R38 R54, 38 | Yageo,RMCF0603JT200K,,,R603,200k,2,R39 R60, 39 | Yageo,RT0603DRE0710KL,,,R603,10k,3,R40 R61 R62, 40 | Stackpole Electronics Inc.,RC1608F133CS,,,R603,13k,1,R41, 41 | Yageo,RC0603JR-070RL,,,R603,0,5,R43 R45 R49 R70 R71, 42 | Yageo,RC1206FR-07976RL,,,R1206,976,4,RS1*A RS1*B RS1A RS1B, 43 | ,,,,R1206,330,2,RS4A RS4B, 44 | ,DG470EQ-T1-E3,,,DG419L-umax,INST,2,SW1 SW2, 45 | Linear,LT1945EMS,Digikey,LT1945EMS#TRPBF-ND,LT1945,INST,1,U1, 46 | Diodes Inc.,DT1042-04SO-7,Digikey,DT1042-04SO-7DICT-ND,HDMIULC6-4SC6,INST,3,U8 U15 U16, 47 | STMicroelectronics,ETP01-2821,Digikey,497-8909-6-ND,ETP01-2821,INST,2,U9 U21, 48 | TI,SN65HVDA100QDRQ1,,,TI_LIN_SN65HVDA100-Q1,INST,2,U22 U24, 49 | STMicroelectronics,ST715MR,,,ST715,INST,1,U23, 50 | NXP,S9S12G96F0CLH,,,S12G96 64-pin,INST,1,U32, 51 | Raltron Electronics,RH100-12.000-8-EXT-TR,,,XTAL-Can,,1,XTAL1, 52 | End of Regular BOM, 53 | DNI List:,CONN2 DS[1-2]A IC2 R[5-6] R[9-11] R23 R12 R14 R75 RS5A RS5B R[29-30] R36 R42 R44 R46 R72 R[31-34] R56 R76 R[78-79] R89 RS2A RS2B RS3A RS3B SS2A SS2B U3 U17 U30 U33, 54 | Board info:, 55 | Board size in mils: 0 x 0 and board size in mm: 0.00 x 0.00, 56 | Parts Counts-> Total_Parts: 103 SM: 0 TH: 103 Unique_Parts: 49 SM: 0 TH: 49, 57 | Counts-> SM-pads: 0 TH-pins: 359, 58 | -------------------------------------------------------------------------------- /Hardware/J3068 LIN EVSE and EV.pcb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udv2g/saej3068-ref/b234655acf6f4aa69f85ebe02fbcec4ec8240a6f/Hardware/J3068 LIN EVSE and EV.pcb -------------------------------------------------------------------------------- /Hardware/J3068 LIN EVSE and EV.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udv2g/saej3068-ref/b234655acf6f4aa69f85ebe02fbcec4ec8240a6f/Hardware/J3068 LIN EVSE and EV.pdf -------------------------------------------------------------------------------- /Hardware/J3068 LIN EVSE and EV.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udv2g/saej3068-ref/b234655acf6f4aa69f85ebe02fbcec4ec8240a6f/Hardware/J3068 LIN EVSE and EV.sch -------------------------------------------------------------------------------- /Info Codes.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udv2g/saej3068-ref/b234655acf6f4aa69f85ebe02fbcec4ec8240a6f/Info Codes.ods -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, udv2g 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /LIN_4_6_5_add_mc9s12g.patch: -------------------------------------------------------------------------------- 1 | diff -ru LIN_Stack/bsp/SCI/lin_isr.c LIN_Stack_add_mc9s12g/bsp/SCI/lin_isr.c 2 | --- LIN_Stack/bsp/SCI/lin_isr.c 2021-06-04 11:35:21.628882000 -0400 3 | +++ LIN_Stack_add_mc9s12g/bsp/SCI/lin_isr.c 2021-06-03 12:41:45.828219400 -0400 4 | @@ -896,7 +896,7 @@ 5 | 6 | #endif /* End if (defined(_MC9S12VR64_H)||defined(_MC9S12VR32_H)) */ 7 | 8 | -#if defined(_MC9S12GN32_H) || defined(_MC9S12G64_H) 9 | +#if defined(_MC9S12GN32_H) || defined(_MC9S12G64_H) || defined(_MC9S12G96_H) //added because missing 10 | /*FUNCTION*--------------------------------------------------------------*//** 11 | * @fn void TIM0_TIMER_ISR (void) 12 | * @brief interrupt interrupt service routine for TIM timer 13 | @@ -919,7 +919,7 @@ 14 | TC0 = (TC0 + ((MCU_BUS_FREQ/1000000)*TIME_BASE_PERIOD) ) & 0xFFFF; 15 | } 16 | 17 | -#endif /* End defined(_MC9S12GN32_H) || defined(_MC9S12G64_H) */ 18 | +#endif /* End defined(_MC9S12GN32_H) || defined(_MC9S12G64_H) || defined(_MC9S12G96_H) */ 19 | 20 | #if (defined(_MC9S12VR64_H) || defined(_MC9S12VR32_H) || defined(_MC9S12VRP64_H) || defined(_MC9S12VRP48_H)) 21 | #if (_SCI0_) 22 | diff -ru LIN_Stack/bsp/SCI/lin_lld_timesrv.c LIN_Stack_add_mc9s12g/bsp/SCI/lin_lld_timesrv.c 23 | --- LIN_Stack/bsp/SCI/lin_lld_timesrv.c 2021-06-04 11:35:21.639028200 -0400 24 | +++ LIN_Stack_add_mc9s12g/bsp/SCI/lin_lld_timesrv.c 2021-06-03 12:41:45.838219300 -0400 25 | @@ -192,7 +192,7 @@ 26 | TSCR1 = 128; 27 | /* End define for I32 */ 28 | 29 | -#elif defined(_MC9S12GN32_H) || defined(_MC9S12G64_H) 30 | +#elif defined(_MC9S12GN32_H) || defined(_MC9S12G64_H) || defined(_MC9S12G96_H) //added because missing 31 | /* Timer functions normally */ 32 | TSCR1 = 8; 33 | /* Set up timer channel 0 */ 34 | @@ -208,7 +208,7 @@ 35 | TC0 = (MCU_BUS_FREQ/1000000)*TIME_BASE_PERIOD; 36 | /* Enable timer */ 37 | TSCR1 = TSCR1_TEN_MASK ; 38 | - /* End define for GN32, G64 */ 39 | + /* End define for GN32, G64, G96 */ 40 | 41 | #elif (defined(_MC9S12VR64_H) || defined(_MC9S12VR32_H)) 42 | /* Timer functions normally */ 43 | diff -ru LIN_Stack/coreapi/lin_common_proto.c LIN_Stack_add_mc9s12g/coreapi/lin_common_proto.c 44 | --- LIN_Stack/coreapi/lin_common_proto.c 2021-06-04 11:35:21.687789100 -0400 45 | +++ LIN_Stack_add_mc9s12g/coreapi/lin_common_proto.c 2022-03-22 11:47:11.571626700 -0400 46 | @@ -1073,7 +1073,7 @@ 47 | l_signal_handle *ptr; 48 | #endif 49 | const lin_configuration *conf; 50 | - const lin_frame_struct *lin_frame_ptr; 51 | + //const lin_frame_struct *lin_frame_ptr; 52 | 53 | /* Multi frame support */ 54 | lin_tl_descriptor *tl_conf; 55 | @@ -1209,7 +1209,7 @@ 56 | l_u8 pid 57 | ) 58 | { 59 | - l_u8 i; 60 | + //l_u8 i; 61 | l_u8 frame_index; 62 | const lin_configuration *conf; 63 | 64 | @@ -1591,6 +1591,7 @@ 65 | } 66 | } 67 | } 68 | +#pragma MESSAGE DISABLE C12056 //debug info incorrect because of optimization or inline assembler 69 | } 70 | #endif /* End of (LIN_MODE == _MASTER_MODE_) */ 71 | /** 72 | diff -ru LIN_Stack/diagnostic/lin_diagnostic_service.c LIN_Stack_add_mc9s12g/diagnostic/lin_diagnostic_service.c 73 | --- LIN_Stack/diagnostic/lin_diagnostic_service.c 2021-06-04 11:35:21.696241900 -0400 74 | +++ LIN_Stack_add_mc9s12g/diagnostic/lin_diagnostic_service.c 2021-06-03 12:41:45.942219300 -0400 75 | @@ -226,12 +226,12 @@ 76 | /*Byte 1: Supplier ID LSB; Byte 2: Supplier ID MSB*/ 77 | if(byte>0 && byte<3) 78 | { 79 | - byte = product_id.supplier_id >> ((byte-1)*8); 80 | + byte = (l_u8)(product_id.supplier_id >> ((byte-1)*8)); //added cast to fix "possible loss of data" 81 | } 82 | /*Byte 3: Function ID LSB; Byte 4: Function ID MSB*/ 83 | else if(byte>2 && byte<5) 84 | { 85 | - byte = product_id.function_id >> ((byte-3)*8); 86 | + byte = (l_u8)(product_id.function_id >> ((byte-3)*8)); //added cast to fix "possible loss of data" 87 | } 88 | /* Byte 5: Variant */ 89 | else 90 | @@ -886,12 +886,12 @@ 91 | /*Byte 1: Supplier ID LSB; Byte 2: Supplier ID MSB*/ 92 | if(byte>0 && byte<3) 93 | { 94 | - byte = (node_conf->product_id).supplier_id >> ((byte-1)*8); 95 | + byte = (l_u8)((node_conf->product_id).supplier_id >> (unsigned char)((byte-1)*8)); //modified to supress warning 96 | } 97 | /*Byte 3: Function ID LSB; Byte 4: Function ID MSB*/ 98 | else if(byte>2 && byte<5) 99 | { 100 | - byte = (node_conf->product_id).function_id >> ((byte-3)*8); 101 | + byte = (l_u8)((node_conf->product_id).function_id >> (unsigned char)((byte-3)*8)); //modified to supress warning 102 | } 103 | /* Byte 5: Variant */ 104 | else 105 | diff -ru LIN_Stack/lowlevel/lin.c LIN_Stack_add_mc9s12g/lowlevel/lin.c 106 | --- LIN_Stack/lowlevel/lin.c 2021-06-04 11:35:21.717005400 -0400 107 | +++ LIN_Stack_add_mc9s12g/lowlevel/lin.c 2021-06-03 12:41:46.013219700 -0400 108 | @@ -58,7 +58,7 @@ 109 | 110 | /* Globle variable */ 111 | #if (LIN_MODE == _SLAVE_MODE_) 112 | -#if (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME__) 113 | +#if (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME_) //remove incorrect _ to fix warning 114 | #if (_LIN_GPIO_ == 0) && !defined(_MC9S08SC4_H) 115 | lin_message_timeout_type tl_check_timeout_type = LD_NO_CHECK_TIMEOUT; /**< timeout type */ 116 | l_u16 tl_check_timeout = N_MAX_TIMEOUT_CNT; /**< timeout counter*/ 117 | @@ -70,7 +70,7 @@ 118 | #if (LIN_MODE == _MASTER_MODE_) 119 | l_u8 etf_collision_flag[LIN_NUM_OF_IFCS] = {0}; 120 | /* Extern globle variable */ 121 | -#if (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME__) 122 | +#if (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME_) 123 | lin_message_timeout_type tl_check_timeout_type_array[LIN_NUM_OF_IFCS] = {LD_NO_CHECK_TIMEOUT}; 124 | l_u16 tl_check_timeout_array[LIN_NUM_OF_IFCS] = {N_MAX_TIMEOUT_CNT}; 125 | #endif 126 | @@ -1038,6 +1038,7 @@ 127 | } 128 | 129 | return (ret); 130 | +#pragma MESSAGE DISABLE C12056 //debug info incorrect because of optimization or inline assembler 131 | } 132 | 133 | l_u8 lin_checksum 134 | diff -ru LIN_Stack/transport/lin_commontl_proto.c LIN_Stack_add_mc9s12g/transport/lin_commontl_proto.c 135 | --- LIN_Stack/transport/lin_commontl_proto.c 2021-06-04 11:35:21.724334000 -0400 136 | +++ LIN_Stack_add_mc9s12g/transport/lin_commontl_proto.c 2022-03-22 11:47:11.576628300 -0400 137 | @@ -59,7 +59,7 @@ 138 | ) 139 | { 140 | lin_tl_pdu_data lin_tl_pdu; 141 | - l_u8 i; 142 | + l_s8 i; 143 | 144 | /* Pack data to response PDU */ 145 | if (sid == SERVICE_ASSIGN_NAD) 146 | @@ -1146,7 +1146,7 @@ 147 | lin_tl_descriptor *tl_conf; 148 | lin_node_attribute *node_conf; 149 | lin_product_id *ident; 150 | - l_u8 i; 151 | + l_s8 i; 152 | /* multi frame support */ 153 | #if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) 154 | lin_tl_pdu_data lin_tl_pdu_buff, *lin_tl_pdu; 155 | -------------------------------------------------------------------------------- /Project/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: LLVM 3 | AlignConsecutiveMacros: true 4 | AlignConsecutiveAssignments: true 5 | AllowShortIfStatementsOnASingleLine: WithoutElse 6 | AllowShortLoopsOnASingleLine: true 7 | ColumnLimit: 0 8 | IndentCaseLabels: true 9 | SortIncludes: false 10 | ... 11 | -------------------------------------------------------------------------------- /Project/C_Layout.hwl: -------------------------------------------------------------------------------- 1 | OPEN source 0 0 60 39 2 | Source < attributes MARKS off 3 | OPEN assembly 60 0 40 31 4 | Assembly < attributes ADR on,CODE off,ABSADR on,SYMB off,TOPPC 0xF88C 5 | OPEN procedure 0 39 60 17 6 | Procedure < attributes VALUES on,TYPES off 7 | OPEN register 60 31 40 25 8 | Register < attributes FORMAT AUTO,COMPLEMENT None 9 | OPEN memory 60 56 40 22 10 | Memory < attributes FORMAT hex,COMPLEMENT None,WORD 1,ASC on,ADR on,ADDRESS 0x80 11 | OPEN data 0 56 60 22 12 | Data:1 < attributes SCOPE global,COMPLEMENT None,FORMAT Symb,MODE automatic,UPDATERATE 10,NAMEWIDTH 16 13 | OPEN data 0 78 60 22 14 | Data:2 < attributes SCOPE local,COMPLEMENT None,FORMAT Symb,MODE automatic,UPDATERATE 10,NAMEWIDTH 16 15 | OPEN command 60 78 40 22 16 | Command < attributes CACHESIZE 1000 17 | bckcolor 50331647 18 | font 'Courier New' 9 BLACK 19 | AUTOSIZE on 20 | ACTIVATE Data:2 Command Procedure Data:1 Source Register Assembly Memory 21 | -------------------------------------------------------------------------------- /Project/Default.mem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udv2g/saej3068-ref/b234655acf6f4aa69f85ebe02fbcec4ec8240a6f/Project/Default.mem -------------------------------------------------------------------------------- /Project/P&E_Multilink_USB.ini: -------------------------------------------------------------------------------- 1 | [STARTUP] 2 | CPUTARGETTYPE=0 3 | USE_CYCLONEPRO_RELAYS=0 4 | PORT=21 5 | interface_selection=1 6 | SHOWDIALOG=0 7 | IO_DELAY_SET=0 8 | frequency_has_changed_old_io_delay_cnt=0 9 | CPUTARGETTYPENAME=HC12/HCS12 - Autodetect Device Type 10 | CyclonePro_poweroffonexit=0 11 | CyclonePro_currentvoltage=255 12 | CyclonePro_PowerDownDelay=250 13 | CyclonePro_PowerUpDelay=250 14 | Multilink_PowerDownDelay=250 15 | Multilink_PowerUpDelay=1000 16 | IO_DELAY_CNT=0 17 | FREQ_FX=4 18 | FREQ_NORMAL=0 19 | FREQ_OSJTAG=0 20 | FREQ_CYCLONE=3 21 | FREQ_TRACELINK=3 22 | FREQ_LIGHTNING=1 23 | FREQ_OPENSDA=0 24 | RESET_DELAY=0 25 | PORT_NAME_STRING= 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | [Environment Variables] 47 | GENPATH={Project}Sources;{Compiler}lib\hc12c\src;{Compiler}lib\hc12c\include;{Compiler}lib\hc12c\lib;{Compiler}lib\xgatec\src;{Compiler}lib\xgatec\include;{Compiler}lib\xgatec\lib 48 | LIBPATH={Compiler}lib\hc12c\include;{Compiler}lib\xgatec\include 49 | OBJPATH={Project}bin 50 | TEXTPATH={Project}bin 51 | ABSPATH={Project}bin 52 | 53 | [HI-WAVE] 54 | Target=icd12 55 | Layout=C_layout.hwl 56 | LoadDialogOptions=AUTOERASEANDFLASH RUNANDSTOPAFTERLOAD="main" 57 | CPU=HC12 58 | MainFrame=0,1,-1,-1,-1,-1,0,24,1440,864 59 | TOOLBAR=57600 57601 32795 0 57635 57634 57637 0 57671 57669 0 32777 32776 32782 32780 32781 32778 0 32806 60 | 61 | 62 | 63 | [HC12MultilinkCyclonePro_GDI_SETTINGS] 64 | CMDFILE0=CMDFILE STARTUP ON ".\cmd\P&E_Multilink_USB_startup.cmd" 65 | CMDFILE1=CMDFILE RESET ON ".\cmd\P&E_Multilink_USB_reset.cmd" 66 | CMDFILE2=CMDFILE PRELOAD ON ".\cmd\P&E_Multilink_USB_preload.cmd" 67 | CMDFILE3=CMDFILE POSTLOAD ON ".\cmd\P&E_Multilink_USB_postload.cmd" 68 | CMDFILE4=CMDFILE VPPON ON ".\cmd\P&E_Multilink_USB_vppon.cmd" 69 | CMDFILE5=CMDFILE VPPOFF ON ".\cmd\P&E_Multilink_USB_vppoff.cmd" 70 | CMDFILE6=CMDFILE UNSECURE ON ".\cmd\P&E_Multilink_USB_erase_unsecure_hcs12p.cmd" 71 | MCUID=0x01C3 72 | NV_PARAMETER_FILE= 73 | NV_SAVE_WSP=0 74 | NV_AUTO_ID=1 75 | 76 | 77 | 78 | 79 | [ICD12] 80 | COMSETTINGS=SETCOMM DRIVER NOPROTOCOL NOPERIODICAL 81 | SETCLKSW=0 82 | HOTPLUGGING=0 83 | DETECTRUNNING=0 84 | RESYNCONCOPRESET=0 85 | BDMAutoSpeed=1 86 | BDMClockSpeed=0 87 | HIGHIODELAYCONSTFORPLL=40 88 | -------------------------------------------------------------------------------- /Project/Project.mcp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udv2g/saej3068-ref/b234655acf6f4aa69f85ebe02fbcec4ec8240a6f/Project/Project.mcp -------------------------------------------------------------------------------- /Project/Project_Data/CWSettingsWindows.stg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udv2g/saej3068-ref/b234655acf6f4aa69f85ebe02fbcec4ec8240a6f/Project/Project_Data/CWSettingsWindows.stg -------------------------------------------------------------------------------- /Project/Project_Data/S12X/TargetDataWindows.tdt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udv2g/saej3068-ref/b234655acf6f4aa69f85ebe02fbcec4ec8240a6f/Project/Project_Data/S12X/TargetDataWindows.tdt -------------------------------------------------------------------------------- /Project/Project_Data/Standard/TargetDataWindows.tdt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udv2g/saej3068-ref/b234655acf6f4aa69f85ebe02fbcec4ec8240a6f/Project/Project_Data/Standard/TargetDataWindows.tdt -------------------------------------------------------------------------------- /Project/Sources/adc_constants.h: -------------------------------------------------------------------------------- 1 | #ifndef _ADC_CONSTANTS_H 2 | #define _ADC_CONSTANTS_H 3 | 4 | // This file is generated by adc_constants.m 5 | 6 | 7 | // MIN/MAX Values for the Pilot states 8 | #define STATE_A_MAX 0xE7 // 13 V 9 | #define STATE_A_NOM 0xDF // 12 V 10 | #define STATE_A_MIN 0xD7 // 11 V 11 | 12 | #define STATE_B_MAX 0xCF // 10 V 13 | #define STATE_B_NOM 0xC8 // 9 V 14 | #define STATE_B_MIN 0xC0 // 8 V 15 | 16 | #define STATE_C_MAX 0xBA // 7.3 V 17 | #define STATE_C_NOM 0xB0 // 6 V 18 | #define STATE_C_MIN 0xA5 // 4.7 V 19 | 20 | #define STATE_D_MAX 0xA0 // 4 V 21 | #define STATE_D_NOM 0x98 // 3 V 22 | #define STATE_D_MIN 0x90 // 2 V 23 | 24 | #define STATE_E_MAX 0x8A // 1.2 V 25 | #define STATE_E_NOM 0x80 // 0 V 26 | #define STATE_E_MIN 0x77 // -1.2 V 27 | 28 | #define STATE_R_MAX 0x5E // -4.3 V 29 | #define STATE_R_NOM 0x56 // -5.3 V 30 | #define STATE_R_MIN 0x4E // -6.3 V 31 | 32 | #define STATE_F_MAX 0x29 // -11 V 33 | #define STATE_F_NOM 0x21 // -12 V 34 | #define STATE_F_MIN 0x17 // -13.2 V 35 | 36 | 37 | // MIN/MAX Values for the Prox states 38 | // Standard prox is not used in J3068, but the code is capable of handling it so we might as well define the values. 39 | #define PROX_STATE_DISCONNECTED_MAX 0xFF // 5 V 40 | #define PROX_STATE_DISCONNECTED_MIN 0xBD // 3.70588 V 41 | 42 | #define PROX_STATE_CONNECTED_OFF_MAX 0xB0 // 3.45098 V 43 | #define PROX_STATE_CONNECTED_OFF_MIN 0x6D // 2.13725 V 44 | 45 | #define PROX_STATE_CONNECTED_ON_MAX 0x65 // 1.98039 V 46 | #define PROX_STATE_CONNECTED_ON_MIN 0x38 // 1.09804 V 47 | 48 | 49 | // J3068/61581-Annex-D Prox 50 | #define IEC_PROX_ERROR_HIGH_MIN 0xF2 // 4.7451 V 51 | 52 | #define IEC_PROX_DISCONNECTED_MAX 0xF1 // 4.72549 V 53 | #define IEC_PROX_DISCONNECTED_MIN 0xDB // 4.29412 V 54 | 55 | #define IEC_PROX_RESERVED_HIGH_MAX 0xDA // 4.27451 V 56 | #define IEC_PROX_RESERVED_HIGH_MIN 0xC8 // 3.92157 V 57 | 58 | #define IEC_PROX_13A_MAX 0xC7 // 3.90196 V 59 | #define IEC_PROX_13A_MIN 0xAF // 3.43137 V 60 | 61 | #define IEC_PROX_20A_MAX 0xAE // 3.41176 V 62 | #define IEC_PROX_20A_MIN 0x98 // 2.98039 V 63 | 64 | #define IEC_PROX_RESERVED_BUTTON_DOWN_MAX 0x97 // 2.96078 V 65 | #define IEC_PROX_RESERVED_BUTTON_DOWN_MIN 0x75 // 2.29412 V 66 | 67 | #define IEC_PROX_32A_MAX 0x74 // 2.27451 V 68 | #define IEC_PROX_32A_MIN 0x59 // 1.7451 V 69 | 70 | #define IEC_PROX_RESERVED_BUTTON_UP_MAX 0x58 // 1.72549 V 71 | #define IEC_PROX_RESERVED_BUTTON_UP_MIN 0x44 // 1.33333 V 72 | 73 | #define IEC_PROX_63A_MAX 0x43 // 1.31373 V 74 | #define IEC_PROX_63A_MIN 0x2F // 0.921569 V 75 | 76 | #define IEC_PROX_RESERVED_LOW_MAX 0x2E // 0.901961 V 77 | #define IEC_PROX_RESERVED_LOW_MIN 0x0D // 0.254902 V 78 | 79 | #define IEC_PROX_ERROR_LOW_MAX 0x0C // 0.235294 V 80 | 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /Project/Sources/canbus.h: -------------------------------------------------------------------------------- 1 | #ifndef __CANBUS_H_ 2 | #define __CANBUS_H_ 3 | 4 | #include "types.h" 5 | #include "hardware.h" 6 | 7 | 8 | /******************************************************* 9 | * Controller Area Network Interrupt (CAN) 10 | ********************************************************/ 11 | 12 | void InitCAN_ExtendedIDs (uint8_t * const base_address, uint8_t mode, uint8_t speed, uint32_t id_ptrn_1, uint32_t mask_ptrn_1, uint32_t id_ptrn_2, uint32_t mask_ptrn_2); 13 | void InitCAN_StandardIDs (uint8_t * const base_address, uint8_t mode, uint8_t speed, uint16_t id_ptrn_1, uint16_t mask_ptrn_1, uint16_t id_ptrn_2, uint16_t mask_ptrn_2, uint16_t id_ptrn_3, uint16_t mask_ptrn_3, uint16_t id_ptrn_4, uint16_t mask_ptrn_4); 14 | 15 | int8_t send_command_CAN(uint8_t * const base_address, uint8_t identifiers, uint32_t id, uint8_t *data, uint8_t msg_size); 16 | 17 | typedef struct { 18 | uint32_t id; 19 | void *obj; 20 | int (*parser) (void *obj, uint8_t *buf, int offset, int buf_size); 21 | int (*handler) (void *obj); 22 | uint8_t process_message_p; 23 | } can_msg_dispatcher_t; 24 | 25 | uint32_t parse_message_CAN(uint8_t * const base_address, uint8_t identifiers, uint8_t table_size, can_msg_dispatcher_t* table); 26 | 27 | #define LISTEN_ONLY_MODE 1 28 | #define NORMAL_MODE 0 29 | 30 | #define STANDARD_IDENTIFIERS 0 31 | #define EXTENDED_IDENTIFIERS 1 32 | 33 | #define CAN250KBAUD 0 34 | #define CAN500KBAUD 1 35 | #define CAN1MBAUD 2 36 | #define CAN20KBAUD 3 37 | #define CAN125KBAUD 4 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /Project/Sources/config.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONFIG_H 2 | #define _CONFIG_H 3 | 4 | //#define CH_A_ONLY 5 | //Behavior is undefined if neither LIN nor PWM are enabled 6 | //#define PWM_CHARGE_ENABLE 7 | #define LIN_CHARGE_ENABLE 8 | 9 | //#define J1939_REQD_FOR_CHARGE 10 | //#define J1939_XMIT 11 | //#define J1939_SEND_SEINFO 12 | 13 | #define INLET_LOCK_TYPE NONE 14 | //#define INLET_LOCK_TYPE FOUR_WIRE 15 | 16 | //#define DISABLE_PROX_CHECKING 17 | 18 | //#define SINGLE_PHASE 19 | //#define TYPE_I_COUPLER //As of now, this does the same thing as SINGLE_PHASE + uses Type I prox levels 20 | 21 | //#define PRE_RELEASE_HARDWARE 22 | //#define WHITEBOARD_HARDWARE 23 | 24 | //#define EV_CONFIG 25 | /**********/ 30 | 31 | #define UART_BAUD 115200 32 | 33 | #define INITIALIZATION_DELAY 1 34 | #define RTI_TICKS_PER_SECOND 926ul //1000/1.08ms This still runs long for some reason FIXME? 35 | #define LOCK_CHECK_DELAY 250 36 | #define SLEEP_CHECK_DELAY 100 37 | 38 | //EV 39 | #define CONNECTION_CLEAR_TIME 2*60*RTI_TICKS_PER_SECOND //Time between connections to assume a new connection is not a restart 40 | #define RAMPDOWN_TIME 2*RTI_TICKS_PER_SECOND //Time to wait for inverter to stop drawing current before requesting disconnect in non-emergency situation 41 | #define VMU_WAKEUP_TIME 60*RTI_TICKS_PER_SECOND //Time to wait for ECU to wake up and request charge before deasserting wakeup signal 42 | 43 | /**/ 55 | 56 | //Connection Types 57 | #define CONNTP_EV_CASE_A 0 58 | #define CONNTP_SE_OUTLET 0 59 | #define CONNTP_TYPE_1 1 60 | #define CONNTP_TYPE_2 2 61 | #define CONNTP_CCS_1 3 62 | #define CONNTP_CCS_2 4 63 | #define CONNTP_3400 5 64 | #define CONNTP_GB_T 6 65 | #define CONNTP_ERROR 0xFE 66 | #define CONNTP_NOTSPECIFIED 0xFF 67 | 68 | //PwrCtrlUnits 69 | #define PCUNITS_PRCT_MAX_WATT 0x00 70 | #define PCUNITS_PHASE_CURRENT 0x01 71 | #define PCUNITS_TOT_WATT 0x02 72 | #define PCUNITS_PRCT_MAX_WATT_VAR 0x08 73 | #define PCUNITS_PHASE_CURRENT_PF 0x09 74 | #define PCUNITS_PHASE_CURRENT_THETA 0x0A 75 | #define PCUNITS_TOT_WATT_VAR 0x0B 76 | 77 | #define PCUNIT_BITMASK(x) (1 << (x)) 78 | 79 | //PwrCtrlModes 80 | #define PCMODES_NORM_CHRG 0xFF 81 | #define PCMODES_CCL 0xB4 82 | #define PCMODES_TC 0xA3 83 | #define PCMODES_TGC 0x9A 84 | #define PCMODES_TC_R 0x8D 85 | #define PCMODES_TGC_R 0x72 86 | #define PCMODES_AUTO_EXT 0x39 87 | #define PCMODES_V2LH 0x17 88 | #define PCMODES_PROCESSING 0x00 89 | #define PCMODES_RSVD_1 0xE8 90 | #define PCMODES_RSVD_2 0xD1 91 | #define PCMODES_RSVD_3 0xC6 92 | #define PCMODES_RSVD_4 0x65 93 | #define PCMODES_RSVD_5 0x5C 94 | #define PCMODES_RSVD_6 0x2E 95 | 96 | #define PCMODES_BITMASK(x) (1 << (((x) >> 4) & 0x0F)) 97 | 98 | //Grid Codes 99 | #define GRIDCODE_UNSUPPORTED 0x0000 100 | #define GRIDCODE_SETTINGS_A 0x0001 101 | #define GRIDCODE_SETTINGS_B 0x0002 102 | #define GRIDCODE_1741_SA 0x0003 103 | #define GRIDCODE_1741_SB 0x0004 104 | 105 | //Sleep States 106 | #define SLEEPSTATE_OFF 0x0 107 | #define SLEEPSTATE_DEEP_ON 0x2 108 | #define SLEEPSTATE_DEEP_OFF 0x3 109 | #define SLEEPSTATE_ON 0x4 110 | #define SLEEPSTATE_TRANSITION 0x5 111 | 112 | //PwrCtrlAuth 113 | #define PCAUTH_NONE 0xF 114 | #define PCAUTH_FORMING 0xA 115 | #define PCAUTH_DISCHARFE 0x5 116 | #define PCAUTH_PROCESSING 0x0 117 | #define PCAUTH_RSVD_1 0x6 118 | #define PCAUTH_RSVD_2 0x9 119 | 120 | /*******/ 164 | /*Ratings>*/ 165 | 166 | /**/ 180 | 181 | /**/ 188 | 189 | /**/ 192 | 193 | #endif 194 | 195 | /* 196 | defines to consider moving here 197 | hardware.h: STATE_CB_TRANSITION_DELAY 198 | lin-cp.h: LIN_DETECT_TIMEOUT 199 | lock.h: DRIVE_TIME 200 | RETRY_DELAY 201 | UNVERIFIED_UNLOCK_DELAY 202 | pilot.c: STATE_A_TRANSITION_DELAY 203 | POWER_UNAVAILABLE_SLEEP_COUNT 204 | scheduler.c DELAY_TABLE_SIZE 205 | */ 206 | -------------------------------------------------------------------------------- /Project/Sources/derivative.h: -------------------------------------------------------------------------------- 1 | #ifdef S12X 2 | 3 | #include 4 | 5 | #pragma LINK_INFO DERIVATIVE "MC9S12XET256" 6 | 7 | #else 8 | 9 | #include 10 | 11 | #pragma LINK_INFO DERIVATIVE "mc9s12g96" 12 | 13 | #endif 14 | 15 | /******************************************************* 16 | * Oscillator 17 | ********************************************************/ 18 | 19 | #ifdef S12X 20 | #define __PLLON PLLCTL_PLLON 21 | #define __REFDIV REFDV_REFDIV 22 | #define __REFFRQ REFDV_REFFRQ 23 | #define __SYNDIV SYNR_SYNDIV 24 | #define __VCOFRQ SYNR_VCOFRQ 25 | #define __POSTDIV POSTDIV_POSTDIV 26 | #define __PLLSEL CLKSEL_PLLSEL 27 | 28 | #define Osc_Enable() (void) 0 29 | #define PLL_Disable() PLLCTL_PLLON = 0 30 | #define PLL_Enable() PLLCTL_PLLON = 1; \ 31 | while(!CRGFLG_LOCK) //Wait till the PLL VCO is within tolerance 32 | #define OSC_Stabilize() (void) 0 33 | 34 | #define COP_Enable() COPCTL = 0b01000101 35 | //101 2^22/12MHZ = .3 sec watchdog 36 | 37 | #else 38 | #define __REFDIV CPMUREFDIV_REFDIV 39 | #define __REFFRQ CPMUREFDIV_REFFRQ 40 | #define __SYNDIV CPMUSYNR_SYNDIV 41 | #define __VCOFRQ CPMUSYNR_VCOFRQ 42 | #define __POSTDIV CPMUPOSTDIV 43 | #define __PLLSEL CPMUCLKS_PLLSEL 44 | #define __SETCOP COPCTL 45 | 46 | #define Osc_Enable() CPMUOSC_OSCE = 1 47 | #define PLL_Disable() (void) 0 48 | #define PLL_Enable() (void) 0 49 | #define OSC_Stabilize() while(!CPMUFLG_UPOSC) 50 | 51 | #define COP_Enable() CPMUCLKS_COPOSCSEL1 = 1; /*set COP to ACLK (10khz)*/ \ 52 | CPMUCOP_CR2 = 1 /*for ACLK 2^13 cycles set 0.8 seconds*/ 53 | #endif 54 | 55 | /******************************************************* 56 | * Analog to Digital Converter (ADC) 57 | ********************************************************/ 58 | 59 | #ifdef S12X 60 | 61 | #define ATDCTL1_SRES ATD0CTL1_SRES 62 | #define ATDCTL1_SMP_DIS ATD0CTL1_SMP_DIS 63 | #define ATDCTL3 ATD0CTL3 64 | #define ATDCTL4_SMP ATD0CTL4_SMP 65 | #define ATDCTL4_PRS ATD0CTL4_PRS 66 | #define ATDCTL5_MULT ATD0CTL5_MULT 67 | #define ATDCTL5_Cx ATD0CTL5_Cx 68 | #define ATDSTAT0_SCF ATD0STAT0_SCF 69 | #define ATDDR0H ATD0DR0H 70 | 71 | #endif 72 | 73 | /******************************************************* 74 | * Real Time Interrupt (RTI) 75 | ********************************************************/ 76 | 77 | #ifdef S12X 78 | #define rti_sel_oscclk() (void) 0 79 | #define __RTI_CTRL_REG RTICTL 80 | #define __RTIE CRGINT_RTIE 81 | #define __RTIF CRGFLG_RTIF 82 | #else 83 | #define rti_sel_oscclk() CPMUCLKS_RTIOSCSEL = 1 84 | #define __RTI_CTRL_REG CPMURTI 85 | #define __RTIE CPMUINT_RTIE 86 | #define __RTIF CPMUFLG_RTIF 87 | #endif 88 | 89 | /******************************************************* 90 | * Timers 91 | ********************************************************/ 92 | 93 | #ifdef S12X 94 | 95 | #define TSCR1_TEN ECT_TSCR1_TEN 96 | 97 | #define OCPD_OCPD6 ECT_OCPD_OCPD6 98 | #define TIOS_IOS6 ECT_TIOS_IOS6 99 | #define CFORC_FOC6 ECT_CFORC_FOC6 100 | #define TTOV_TOV6 ECT_TTOV_TOV6 101 | #define TIE_C6I ECT_TIE_C6I 102 | #define TC6 ECT_TC6 103 | #define TFLG1_C6F ECT_TFLG1_C6F 104 | 105 | #define OCPD_OCPD1 ECT_OCPD_OCPD1 106 | #define TIOS_IOS1 ECT_TIOS_IOS1 107 | #define CFORC_FOC1 ECT_CFORC_FOC1 108 | #define TTOV_TOV1 ECT_TTOV_TOV1 109 | #define TIE_C1I ECT_TIE_C1I 110 | #define TC1 ECT_TC1 111 | #define TCNT ECT_TCNT 112 | #define TFLG1_C1F ECT_TFLG1_C1F 113 | 114 | #define VectorNumber_Vtimer1 VectorNumber_Vectch1 115 | #define VectorNumber_Vtimer6 VectorNumber_Vectch6 116 | 117 | #else 118 | 119 | #define VectorNumber_Vtimer1 VectorNumber_Vtimch1 120 | #define VectorNumber_Vtimer6 VectorNumber_Vtimch6 121 | 122 | #endif 123 | 124 | /******************************************************* 125 | * Controller Area Network Interrupt (CAN) 126 | ********************************************************/ 127 | 128 | #ifdef S12X 129 | #define CANCTL1_CANE_MASK CAN0CTL1_CANE_MASK 130 | #define CANCTL0_INITRQ_MASK CAN0CTL0_INITRQ_MASK 131 | #define CANCTL0_WUPE_MASK CAN0CTL0_WUPE_MASK 132 | #define CANCTL1_INITAK_MASK CAN0CTL1_INITAK_MASK 133 | #define CANCTL1_WUPM_MASK CAN0CTL1_WUPM_MASK 134 | #define CANCTL1_LISTEN_MASK CAN0CTL1_LISTEN_MASK 135 | #define CANRIER_WUPIE_MASK CAN0RIER_WUPIE_MASK 136 | #define CANRIER_RXFIE_MASK CAN0RIER_RXFIE_MASK 137 | #else 138 | #define VectorNumber_Vcan0rx VectorNumber_Vcanrx 139 | #define VectorNumber_Vcan0tx VectorNumber_Vcantx 140 | #define CAN0RFLG CANRFLG 141 | #define VectorNumber_Vcan0wkup VectorNumber_Vcanwkup 142 | #define CAN0RFLG_WUPIF CANRFLG_WUPIF 143 | #endif 144 | 145 | /******************************************************* 146 | * Pointers 147 | ********************************************************/ 148 | 149 | #ifdef S12X 150 | #define _FAR_ far 151 | #else 152 | #define _FAR_ 153 | #endif 154 | -------------------------------------------------------------------------------- /Project/Sources/evse_smarts.c: -------------------------------------------------------------------------------- 1 | #include "evse_smarts.h" 2 | #include "pilot.h" 3 | #include "globals.h" 4 | #include "hardware.h" 5 | #include "string_utils.h" 6 | 7 | void evse_set_c(struct evse_state_t *evse_state, three_phase_currents_t current) { 8 | // clang-format off 9 | //if (current.pwm < evse_state->min_c.pwm) current.pwm = evse_state->min_c.pwm; 10 | //if (current.C1_L1 < evse_state->min_c.C1_L1) current.C1_L1 = evse_state->min_c.C1_L1; 11 | //if (current.C2_L2 < evse_state->min_c.C2_L2) current.C2_L2 = evse_state->min_c.C2_L2; 12 | //if (current.C3_L3 < evse_state->min_c.C3_L3) current.C3_L3 = evse_state->min_c.C3_L3; 13 | //if (current.C4_N < evse_state->min_c.C4_N) current.C4_N = evse_state->min_c.C4_N; 14 | 15 | if (current.pwm > evse_state->max_c.pwm) current.pwm = evse_state->max_c.pwm; 16 | if (current.C1_L1 > evse_state->max_c.C1_L1) current.C1_L1 = evse_state->max_c.C1_L1; 17 | if (current.C2_L2 > evse_state->max_c.C2_L2) current.C2_L2 = evse_state->max_c.C2_L2; 18 | if (current.C3_L3 > evse_state->max_c.C3_L3) current.C3_L3 = evse_state->max_c.C3_L3; 19 | if (current.C4_N > evse_state->max_c.C4_N) current.C4_N = evse_state->max_c.C4_N; 20 | // clang-format on 21 | 22 | evse_state->set_c = DetermineEvMaxC(evse_state->ch, current); //Cap set_c to highest allowed value 23 | 24 | evse_state->set_c = current; 25 | evse_state->duty = amps2duty(evse_state->set_c.pwm); 26 | //(void)SendStatusMessage(); 27 | 28 | //SetPilotADutyCycle(evse_state->duty); 29 | evse_state->command_not_received_count = 0; 30 | } 31 | 32 | void evse_set_d(struct evse_state_t *evse_state, uint8_t current) { 33 | //FIXME needs more limit checks like evse_set_c 34 | 35 | evse_state->command_not_received_count = 0; 36 | } 37 | 38 | uint32_t command_evse(struct evse_state_t *evse_state) { 39 | ++evse_state->command_not_received_count; 40 | /* If the maximum charge rate is set to a value that is 41 | * *NOT* equal to the default rate AND 42 | * and we have not received a commend from higher up for 43 | * the designated wait period, revert to the default rate 44 | */ 45 | if (evse_state->command_not_received_count > EVSE_DECREASE_SET_C_WAIT_PERIOD) { 46 | evse_set_c(evse_state, evse_state->default_c);; 47 | 48 | PrintConsoleString("resetting to DEF_C",0); 49 | } 50 | 51 | return EVSE_MAIN_LOOP; 52 | } 53 | 54 | void evse_init_defaults(uint8_t ch, struct evse_state_t *evse_state) { 55 | //evse_state->min_c.pwm = EVSE_MIN_C; 56 | //evse_state->min_c.C1_L1 = EVSE_MIN_C; 57 | //evse_state->min_c.C2_L2 = EVSE_MIN_C; 58 | //evse_state->min_c.C3_L3 = EVSE_MIN_C; 59 | //evse_state->min_c.C4_N = EVSE_MIN_C; 60 | 61 | evse_state->max_c.pwm = SE_MAX_CURRENT_N; //if L and N dfffer, N should always be smaller 62 | evse_state->max_c.C1_L1 = SE_MAX_CURRENT_L; 63 | evse_state->max_c.C2_L2 = SE_MAX_CURRENT_L; 64 | evse_state->max_c.C3_L3 = SE_MAX_CURRENT_L; 65 | evse_state->max_c.C4_N = SE_MAX_CURRENT_N; 66 | 67 | evse_state->default_c.pwm = SE_MAX_CURRENT_N; 68 | evse_state->default_c.C1_L1 = SE_MAX_CURRENT_L; 69 | evse_state->default_c.C2_L2 = SE_MAX_CURRENT_L; 70 | evse_state->default_c.C3_L3 = SE_MAX_CURRENT_L; 71 | evse_state->default_c.C4_N = SE_MAX_CURRENT_N; 72 | 73 | evse_state->set_c = evse_state->default_c; //copy entire structure 74 | evse_state->command_not_received_count = 0; 75 | 76 | evse_state->set_c = DetermineEvMaxC(evse_state->ch, evse_state->set_c); //Cap set_c to highest allowed value 77 | 78 | evse_state->duty = amps2duty(evse_state->set_c.pwm); 79 | evse_state->ch = ch; 80 | } 81 | 82 | void EVSE_Init(struct evse_state_t *evse_state) { 83 | evse_init_current(evse_state); 84 | } 85 | 86 | void evse_init_current(struct evse_state_t *evse_state) { 87 | evse_state->set_c = evse_state->default_c; 88 | evse_state->command_not_received_count = 0; 89 | 90 | evse_state->set_c = DetermineEvMaxC(evse_state->ch, evse_state->set_c); //Cap set_c to highest allowed value 91 | 92 | evse_state->duty = amps2duty(evse_state->set_c.pwm); 93 | } 94 | -------------------------------------------------------------------------------- /Project/Sources/evse_smarts.h: -------------------------------------------------------------------------------- 1 | #ifndef __EVSE_SMARTS_H_ 2 | #define __EVSE_SMARTS_H_ 3 | 4 | #include "types.h" 5 | 6 | typedef struct { 7 | uint8_t pwm; 8 | uint8_t C1_L1; 9 | uint8_t C2_L2; 10 | uint8_t C3_L3; 11 | uint8_t C4_N; 12 | } three_phase_currents_t; 13 | 14 | struct evse_state_t { 15 | //three_phase_currents_t min_c; 16 | three_phase_currents_t max_c; 17 | three_phase_currents_t default_c; 18 | three_phase_currents_t set_c; 19 | 20 | uint8_t command_not_received_count; 21 | uint16_t nominal_voltage; 22 | 23 | uint8_t duty; 24 | uint8_t ch; 25 | }; 26 | 27 | void evse_init_defaults(uint8_t ch, struct evse_state_t *evse_state); 28 | void EVSE_Init(struct evse_state_t *evse_state); 29 | void evse_init_current(struct evse_state_t *evse_state); 30 | uint32_t command_evse(struct evse_state_t *evse_state); 31 | void evse_set_c(struct evse_state_t *evse_state, three_phase_currents_t current); 32 | void evse_set_d(struct evse_state_t *evse_state, uint8_t current); 33 | 34 | void InitMonitoring(void); 35 | void InitVoltagePhases(void); 36 | uint32_t rcd_relay_monitor(void *); 37 | void PrintRCDTransceiverStats(void); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /Project/Sources/globals.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "pilot.h" 3 | #include "sci.h" 4 | #include "hardware.h" 5 | #include "evse_smarts.h" 6 | #include "lin-cp.h" 7 | #include "lock.h" 8 | #include "ids_handler.h" 9 | #include "j3072_handler.h" 10 | 11 | int8_t SCI2_receive_buffer[255]; 12 | uint8_t SCI2_receive_pointer = 0; 13 | uint8_t SCI2_receive_flag = FALSE; 14 | 15 | uint8_t debug_gate = FALSE; 16 | bool timebase_flag = FALSE; 17 | 18 | bool j1939_charge_desired[2] = {FALSE,FALSE}; 19 | 20 | /*******************/ 31 | 32 | /*******************/ 35 | 36 | /*******************/ 40 | 41 | /*******************/ 48 | 49 | 50 | /*******************/ 54 | 55 | /*******************/ 59 | -------------------------------------------------------------------------------- /Project/Sources/globals.h: -------------------------------------------------------------------------------- 1 | #ifndef __GLOBALS_H_ 2 | #define __GLOBALS_H_ 3 | 4 | #include "pilot.h" 5 | #include "sci.h" 6 | #include "evse_smarts.h" 7 | #include "hardware.h" 8 | #include "lin-cp.h" 9 | 10 | extern int8_t SCI2_receive_buffer[]; 11 | extern uint8_t SCI2_receive_pointer; 12 | extern uint8_t SCI2_receive_flag; 13 | 14 | extern uint8_t debug_gate; 15 | extern bool timebase_flag; 16 | 17 | extern bool j1939_charge_desired[2]; 18 | 19 | /*******************/ 30 | 31 | /*******************/ 34 | 35 | /*******************/ 39 | 40 | /*******************/ 49 | 50 | /*******************/ 54 | 55 | /*******************/ 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /Project/Sources/hardware.h: -------------------------------------------------------------------------------- 1 | #ifndef _HARDWARE_H 2 | #define _HARDWARE_H 3 | 4 | #include "types.h" 5 | #include "config.h" 6 | 7 | #define A 0 8 | #define B 1 9 | 10 | /******************************************************* 11 | * Configuration 12 | ********************************************************/ 13 | 14 | void init_hardware(void); 15 | void init_timers(void); 16 | void configure_oscillator(void); 17 | void init_io(void); 18 | void init_pwm(void); 19 | void InitRTI(void); 20 | 21 | uint32_t sleepCheck(void *); 22 | 23 | /******************************************************* 24 | * Constants 25 | ********************************************************/ 26 | 27 | #define EDGE_BACKOFF_TIME_US 6 //Delay to allow Pilot lines to settle before sampling 28 | 29 | 30 | /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * 31 | * The types of PROX states 32 | * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 33 | // DOMAIN : prox_type_t 34 | #define PROX_J1772 1 35 | #define PROX_IEC61851 2 36 | // END prox_type_t 37 | 38 | /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * 39 | * The defined set of Lock Types 40 | * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 41 | // DOMAIN : lock_type_t 42 | #define NONE 1 43 | #define FOUR_WIRE 2 44 | // END lock_type_t 45 | 46 | /******************************************************* 47 | * Delay Functions 48 | ********************************************************/ 49 | 50 | void DelayMs(uint16_t ms); 51 | void DelayUs(uint16_t us); 52 | 53 | /******************************************************* 54 | * Interrupt Helper Functions 55 | ********************************************************/ 56 | 57 | uint8_t check_interrupts_disabled(void); 58 | 59 | /******************************************************* 60 | * Analog to Digital Converter (ADC/ATD) 61 | ********************************************************/ 62 | #define ATDPILOTACH 0 63 | #define ATDPROXACH 2 64 | #define ATDPILOTBCH 1 65 | #define ATDPROXBCH 3 66 | //#define ATD12PLUSCH 0 67 | //#define ATD12MINUSCH 0 68 | //#define ATD12BATTCH 0 69 | 70 | #define PILOTA_WAKEUP_INTERRUPT_ENABLE PIEP_PIEP2 71 | #define PILOTA_WAKEUP_INTERRUPT_FLAG PIFP_PIFP2 72 | #define PILOTA_WAKEUP_INTERRUPT_POLARITY PPSP_PPSP2 73 | 74 | #define PILOTB_WAKEUP_INTERRUPT_ENABLE PIEP_PIEP3 75 | #define PILOTB_WAKEUP_INTERRUPT_FLAG PIFP_PIFP3 76 | #define PILOTB_WAKEUP_INTERRUPT_POLARITY PPSP_PPSP3 77 | 78 | void InitADC(void); 79 | 80 | uint8_t PilotAReadADC(void); 81 | uint8_t PilotBReadADC(void); 82 | 83 | uint8_t ProxAReadADC(void); 84 | uint8_t ProxBReadADC(void); 85 | 86 | /******************************************************* 87 | * Port I/O Macros 88 | ********************************************************/ 89 | 90 | //block 1 (top left) 91 | #define UC_PILOT_B_STATE_C PTT_PTT5 92 | #define UC_PILOT_B_STATE_B PTT_PTT4 93 | #define UC_PILOT_A_STATE_C PTT_PTT3 94 | #define UC_PILOT_A_STATE_B PTT_PTT2 95 | 96 | 97 | #if defined(PRE_RELEASE_HARDWARE) 98 | #define CONTACTOR_B_CLOSE PTJ_PTJ4 99 | #define CONTACTOR_B_ERROR PTJ_PTJ5 100 | #define CONTACTOR_A_ERROR PTJ_PTJ6 101 | #define CONTACTOR_A_CLOSE PTJ_PTJ7 102 | 103 | #elif defined(WHITEBOARD_HARDWARE) 104 | #define CONTACTOR_B_CLOSE PT0AD_PT0AD6 //NOTE inverted logic 105 | #define CONTACTOR_B_ERROR PTJ_PTJ5 106 | #define CONTACTOR_A_ERROR PTJ_PTJ6 107 | #define CONTACTOR_A_CLOSE PT0AD_PT0AD7 //NOTE inverted logic 108 | 109 | #else 110 | #define CONTACTOR_B_ERROR PTT_PTT5 111 | #define CONTACTOR_B_CLOSE PTT_PTT4 112 | #define CONTACTOR_A_ERROR PTT_PTT3 113 | #define CONTACTOR_A_CLOSE PTT_PTT2 114 | #endif 115 | 116 | #define CAN_SLEEP PTT_PTT1 117 | 118 | //block 3 119 | #define OVER_TEMP_CUTOUT PTP_PTP7 120 | 121 | #if defined(WHITEBOARD_HARDWARE) 122 | #define PWM_A PTP_PTP4 123 | #define PWM_B PTP_PTP5 124 | #define PILOT_DET_A PTP_PTP2 125 | #define PILOT_DET_B PTP_PTP3 126 | 127 | #define CHARGE_LED_A PTP_PTP6 128 | #define CHARGE_LED_B PTP_PTP7 129 | 130 | #else 131 | #define PWM_A PTP_PTP5 132 | #define PWM_B PTP_PTP4 133 | #define PILOT_DET_B PTP_PTP3 134 | #define PILOT_DET_A PTP_PTP2 135 | #endif 136 | 137 | //block 4 138 | #ifndef S12X 139 | 140 | #define LIN_A_ENABLE PTJ_PTJ0 141 | #define LIN_B_ENABLE PTJ_PTJ1 142 | #define VMU_WAKEUP PTJ_PTJ2 143 | #define SLEEP_SHDN PTJ_PTJ3 144 | #define UC_SENSE_SIGNAL_A_LOCK PTJ_PTJ4 145 | #define UC_SENSE_SIGNAL_A_UNLOCK PTJ_PTJ5 146 | #define UC_SENSE_SIGNAL_B_LOCK PTJ_PTJ6 147 | #define UC_SENSE_SIGNAL_B_UNLOCK PTJ_PTJ7 148 | 149 | #else 150 | 151 | #define LIN_A_ENABLE PORTA_PA0 152 | #define LIN_B_ENABLE PORTA_PA1 153 | #define VMU_WAKEUP PORTA_PA2 154 | #define SLEEP_SHDN PORTA_PA3 155 | #define UC_SENSE_SIGNAL_A_LOCK PORTA_PA4 156 | #define UC_SENSE_SIGNAL_A_UNLOCK PORTA_PA5 157 | #define UC_SENSE_SIGNAL_B_LOCK PORTA_PA6 158 | #define UC_SENSE_SIGNAL_B_UNLOCK PORTA_PA7 159 | 160 | #endif 161 | //block 7 162 | 163 | #ifndef S12X 164 | #define RELAY_CONTROL_B_PLUS PT0AD_PT0AD7 165 | #define RELAY_CONTROL_B_MINUS PT0AD_PT0AD6 166 | #define RELAY_CONTROL_A_PLUS PT0AD_PT0AD5 167 | #define RELAY_CONTROL_A_MINUS PT0AD_PT0AD4 168 | 169 | #define PWM_ENABLE_B PT0AD_PT0AD2 170 | #define PWM_ENABLE_A PT0AD_PT0AD1 171 | 172 | #else 173 | #define RELAY_CONTROL_B_PLUS PORTB_PB7 174 | #define RELAY_CONTROL_B_MINUS PORTB_PB6 175 | #define RELAY_CONTROL_A_PLUS PORTB_PB5 176 | #define RELAY_CONTROL_A_MINUS PORTB_PB4 177 | #define CAN4_SLEEP PORTB_PB3 178 | #define PWM_ENABLE_B PORTB_PB2 179 | #define PWM_ENABLE_A PORTB_PB1 180 | #define CAN1_SLEEP PORTB_PB0 181 | #endif 182 | 183 | #define SET_PWM_PIN(x,y) if(x) { PWM_B = (y); } else { PWM_A = (y); } 184 | 185 | /******************************************************* 186 | * PWM 187 | ********************************************************/ 188 | 189 | #if defined(WHITEBOARD_HARDWARE) 190 | #define EnablePWMA() PWME_PWME4 = 1 191 | #define DisablePWMA() PWME_PWME4 = 0 192 | #define EnablePWMB() PWME_PWME5 = 1 193 | #define DisablePWMB() PWME_PWME5 = 0 194 | #define SetPilotADutyCycleRaw(d) PWMDTY4 = d 195 | #define SetPilotBDutyCycleRaw(d) PWMDTY5 = d 196 | 197 | #else 198 | #define EnablePWMA() PWME_PWME5 = 1 199 | #define DisablePWMA() PWME_PWME5 = 0 200 | #define EnablePWMB() PWME_PWME4 = 1 201 | #define DisablePWMB() PWME_PWME4 = 0 202 | #define SetPilotADutyCycleRaw(d) PWMDTY5 = d 203 | #define SetPilotBDutyCycleRaw(d) PWMDTY4 = d 204 | #endif 205 | 206 | 207 | #define EnablePWM(x) if(x) { EnablePWMB(); } else { EnablePWMA(); } 208 | #define DisablePWM(x) if(x) { DisablePWMB(); } else { DisablePWMA(); } 209 | #define SetPilotDutyCycleRaw(x,y) if(x) { SetPilotBDutyCycleRaw(y); } else { SetPilotADutyCycleRaw(y); } 210 | 211 | /******************************************************* 212 | * Controller Area Network Interrupt (CAN) 213 | ********************************************************/ 214 | 215 | #ifdef S12X 216 | #define CAN0_BASE_ADDRESS &CAN0CTL0 217 | #define CAN1_BASE_ADDRESS &CAN1CTL0 218 | #define CAN4_BASE_ADDRESS &CAN4CTL0 219 | 220 | #else 221 | #define CAN0_BASE_ADDRESS &CANCTL0 222 | #endif 223 | 224 | /******************************************************* 225 | * (EV) States 226 | ********************************************************/ 227 | 228 | #ifdef PRE_RELEASE_HARDWARE 229 | 230 | #define SetAStateA() UC_PILOT_A_STATE_B = 0; UC_PILOT_A_STATE_C = 0 231 | #define SetAStateB() UC_PILOT_A_STATE_B = 0; UC_PILOT_A_STATE_C = 1 232 | #define SetAStateC() UC_PILOT_A_STATE_B = 1; UC_PILOT_A_STATE_C = 0 233 | 234 | #define SetBStateA() UC_PILOT_B_STATE_B = 0; UC_PILOT_B_STATE_C = 0 235 | #define SetBStateB() UC_PILOT_B_STATE_B = 0; UC_PILOT_B_STATE_C = 1 236 | #define SetBStateC() UC_PILOT_B_STATE_B = 1; UC_PILOT_B_STATE_C = 0 237 | 238 | #else 239 | 240 | #define SetAStateA() UC_PILOT_A_STATE_B = 0; UC_PILOT_A_STATE_C = 0 241 | #define SetAStateB() UC_PILOT_A_STATE_B = 1; UC_PILOT_A_STATE_C = 0 242 | #define SetAStateC() UC_PILOT_A_STATE_B = 1; UC_PILOT_A_STATE_C = 1 243 | 244 | #define SetBStateA() UC_PILOT_B_STATE_B = 0; UC_PILOT_B_STATE_C = 0 245 | #define SetBStateB() UC_PILOT_B_STATE_B = 1; UC_PILOT_B_STATE_C = 0 246 | #define SetBStateC() UC_PILOT_B_STATE_B = 1; UC_PILOT_B_STATE_C = 1 247 | 248 | #endif 249 | 250 | #define SetStateA(x) if(x) { SetBStateA(); } else { SetAStateA(); } 251 | #define SetStateB(x) if(x) { SetBStateB(); } else { SetAStateB(); } 252 | #define SetStateC(x) if(x) { SetBStateC(); } else { SetAStateC(); } 253 | 254 | #endif -------------------------------------------------------------------------------- /Project/Sources/ids_handler.h: -------------------------------------------------------------------------------- 1 | #ifndef IDS_HANDLER_H 2 | #define IDS_HANDLER_H 3 | 4 | enum {ID_INCOMPLETE = 0, ID_COMPLETE, DATA}; 5 | 6 | bool id_parse(uint8_t ch); 7 | void id_xmit(uint8_t ch, uint8_t page); 8 | 9 | void data_parse(uint8_t ch); 10 | void data_xmit(uint8_t ch, uint8_t page); 11 | 12 | void ids_init(uint8_t ch); 13 | void on_id_frame_receipt(uint8_t ch); 14 | void on_id_frame_xmit(uint8_t ch); 15 | 16 | void copy_buffer_data(uint8_t * _FAR_ source, uint8_t * _FAR_ destination, uint8_t size, bool string); 17 | void invalidate_bytes_page(uint8_t * buffer, uint8_t mask); 18 | 19 | #define EVSTATUSINLETLATCH_RELEASED 0x00 20 | #define EVSTATUSINLETLATCH_ENGAGED 0x01 21 | #define EVSTATUSINLETLATCH_ERROR 0x02 22 | #define EVSTATUSINLETLATCH_NOT_AVAILABLE 0x03 23 | #define EVSTATUSINLETOVERRIDE_NOT_ACTIVE 0x00 24 | #define EVSTATUSINLETOVERRIDE_ACTIVE 0x01 25 | #define EVSTATUSINLETOVERRIDE_ERROR 0x02 26 | #define EVSTATUSINLETOVERRIDE_NOT_AVAILABLE 0x03 27 | #define EVSTATUSINLETLOCK_UNLOCKED 0x00 28 | #define EVSTATUSINLETLOCK_LOCKED 0x01 29 | #define EVSTATUSINLETLOCK_IN_TRANSITION 0x02 30 | #define EVSTATUSINLETLOCK_NO_LOCK 0x05 31 | #define EVSTATUSINLETLOCK_ERROR 0x06 32 | #define EVSTATUSINLETLOCK_NOT_AVAILABLE 0x07 33 | #define EVSTATUSCELLVOLTDIFF_WITHIN_ACCEPTABLE_LIMITS 0x00 34 | #define EVSTATUSCELLVOLTDIFF_CAN_BE_CORRECTED 0x01 35 | #define EVSTATUSCELLVOLTDIFF_MAINTENANCE_CAN_RESTORE_PERFORMANCE 0x02 36 | #define EVSTATUSCELLVOLTDIFF_MAINTENANCE_CANNOT_RESTORE_PERFORMANCE 0x03 37 | #define EVSTATUSCELLVOLTDIFF_PERFORMANCE_RESTORATION_UNKNOWN 0x04 38 | #define EVSTATUSCELLVOLTDIFF_ERROR 0x0E 39 | #define EVSTATUSCELLVOLTDIFF_NOT_AVAILABLE 0x0F 40 | #define EVSTATUSCELLBAL_BALANCED 0x00 41 | #define EVSTATUSCELLBAL_UNBALANCED 0x01 42 | #define EVSTATUSCELLBAL_ERROR 0x02 43 | #define EVSTATUSCELLBAL_NOT_AVAILABLE 0x03 44 | #define EVACTIVECELLBAL_NOT_ACTIVE 0x00 45 | #define EVACTIVECELLBAL_ACTIVE 0x01 46 | #define EVACTIVECELLBAL_ERROR 0x02 47 | #define EVACTIVECELLBAL_NOT_AVAILABLE 0x03 48 | 49 | #define SERMTMGMTSTATUS_CONNECTED 0x00 50 | #define SERMTMGMTSTATUS_CONNECTING 0x01 51 | #define SERMTMGMTSTATUS_NOT_CONNECTED 0x02 52 | #define SERMTMGMTSTATUS_FALLBACK 0x03 53 | #define SERMTMGMTSTATUS_LOCAL 0x04 54 | #define SERMTMGMTSTATUS_ERROR 0xFE 55 | #define SERMTMGMTSTATUS_NONE_OR_STATUS_UNKNOWN 0xFF 56 | #define SEEVTRIPSTATUS_NOT_PRESENT 0x00 57 | #define SEEVTRIPSTATUS_FOLLOWING 0x01 58 | #define SEEVTRIPSTATUS_CANNOT_BE_MET 0x02 59 | #define SEEVTRIPSTATUS_INVALID 0xFE 60 | #define SEEVTRIPSTATUS_NOT_SUPPORTED 0xFF 61 | #define SESETRIPSTATUS_NOT_PRESENT 0x00 62 | #define SESETRIPSTATUS_FOLLOWING 0x01 63 | #define SESETRIPSTATUS_CANNOT_BE_MET 0x02 64 | #define SESETRIPSTATUS_EV_PRECEDENCE 0x03 65 | #define SESETRIPSTATUS_CANNOT_RETRIEVE 0xFE 66 | #define SESETRIPSTATUS_NOT_SUPPORTED 0xFF 67 | 68 | typedef struct { 69 | uint8_t EvVIN[18]; 70 | uint8_t EvSerialNum[43]; 71 | uint8_t EvVehicleName[22]; 72 | uint8_t EvFirmwareRevision[29]; 73 | uint8_t EvManufacturer[43]; 74 | } ev_ids_strings_t; 75 | 76 | typedef struct { 77 | uint8_t SeEVSEID[41]; 78 | uint8_t SeSECCID[71]; 79 | uint8_t SeSerialNum[43]; 80 | uint8_t SeFirmwareRevision[29]; 81 | uint8_t SeManufacturer[43]; 82 | uint8_t SePublicName[43]; 83 | } se_ids_strings_t; 84 | 85 | typedef struct { 86 | uint32_t EvOdometer; 87 | uint8_t EvStatusInletLatch; 88 | uint8_t EvStatusInletOverride; 89 | uint8_t EvStatusInletLock; 90 | uint32_t EvHVESSDishargeCapacity; 91 | uint32_t EvHVESSChargeCapacity; 92 | uint16_t EvHVESSRange; 93 | uint16_t EvEVTimeToEnergyForDept; 94 | uint16_t EvDurMin; 95 | uint16_t EvChaDurMax; 96 | uint16_t EvDschDurMax; 97 | uint8_t EvTimeReqNum; 98 | uint16_t EvEVTimeToRange; 99 | uint16_t EvEVTimeToEnergy; 100 | uint16_t EvHVESSVoltage; 101 | uint16_t EvHVESSCurrent; 102 | uint8_t EvHVESSHealth; 103 | uint8_t EvHVESSUserSOC; 104 | uint16_t EvACActivePower; 105 | uint16_t EvACReactivePower; 106 | uint8_t EvACFrequency; 107 | uint16_t EvL1NVolts; 108 | uint16_t EvL2NVolts; 109 | uint16_t EvL3NVolts; 110 | uint16_t EvAmbientTemp; 111 | uint16_t EvCabinTemp; 112 | uint16_t EvHVESSCellTemp; 113 | uint16_t EvMaxHVESSTemp; 114 | uint16_t EvMinHVESSTemp; 115 | uint8_t EvHVESSElecTemp; 116 | uint16_t EvMaxHVESSCellVolt; 117 | uint16_t EvMinHVESSCellVolt; 118 | uint16_t EvNumHVESSCellBalancing; 119 | uint8_t EvStatusCellVoltDiff; 120 | uint8_t EvStatusCellBal; 121 | uint8_t EvActiveCellBal; 122 | uint16_t EvChargerTemp; 123 | uint16_t EvMaxChargerTemp; 124 | uint8_t EvInletTemp; 125 | uint8_t EvHVESSTemp; 126 | } ev_data_vars_t; 127 | 128 | typedef struct { 129 | uint8_t SeRmtMgmtStatus; 130 | uint8_t SeEvTripStatus; 131 | uint8_t SeSeTripStatus; 132 | uint8_t SeExptTripPerct; 133 | uint8_t SeTimeReqNum; 134 | uint16_t SeHVESSRangeCalc; 135 | uint32_t SeHVESSEnergyCalc; 136 | } se_data_vars_t; 137 | 138 | typedef struct { 139 | ev_ids_strings_t s; 140 | } ev_ids_t; 141 | 142 | typedef struct { 143 | se_ids_strings_t s; 144 | } se_ids_t; 145 | 146 | typedef struct { 147 | ev_data_vars_t v; 148 | } ev_data_t; 149 | 150 | typedef struct { 151 | se_data_vars_t v; 152 | } se_data_t; 153 | 154 | #ifdef EV_CONFIG 155 | extern ev_data_t * _FAR_ inact_data_xmit[]; 156 | #else 157 | extern se_data_t * _FAR_ inact_data_xmit[]; 158 | #endif 159 | 160 | #endif -------------------------------------------------------------------------------- /Project/Sources/info_code_handler.c: -------------------------------------------------------------------------------- 1 | #include "lin-cp.h" 2 | #include "globals.h" 3 | #include "info_codes.h" 4 | #include "info_code_handler.h" 5 | #include "utils.h" 6 | 7 | # include "InfoCodeStrings.h" //not a proper header, be careful 8 | 9 | #ifdef EV_CONFIG 10 | #define XMIT_BUFFER_SIZE MAX_EVINFOENTRIES 11 | #define RCV_BUFFER_SIZE MAX_SEINFOENTRIES * 2 //We know exactly how many codes we can possibly send, but can't know what we might receive 12 | #define XMIT_INFOENTRY_EMPTY EVINFOENTRY_EMPTY 13 | #define RCV_INFOENTRY_EMPTY SEINFOENTRY_EMPTY 14 | #define XMIT_INFO(x) EvInfo##x 15 | #define RCV_INFO(x) SeInfo##x 16 | #define MY_ID "EV" 17 | #define OTHER_ID "SE" 18 | #define MY_ID_BOOL FALSE 19 | #else 20 | #define XMIT_BUFFER_SIZE MAX_SEINFOENTRIES 21 | #define RCV_BUFFER_SIZE MAX_EVINFOENTRIES * 2 22 | #define XMIT_INFOENTRY_EMPTY SEINFOENTRY_EMPTY 23 | #define RCV_INFOENTRY_EMPTY EVINFOENTRY_EMPTY 24 | #define XMIT_INFO(x) SeInfo##x 25 | #define RCV_INFO(x) EvInfo##x 26 | #define MY_ID "SE" 27 | #define OTHER_ID "EV" 28 | #define MY_ID_BOOL TRUE 29 | #endif 30 | 31 | //Initialize the first page to Empty 32 | static uint8_t info_codes_xmit_buff_1[2][XMIT_BUFFER_SIZE] = {{XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY, 33 | XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY}, 34 | {XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY, 35 | XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY}}; 36 | static uint8_t info_codes_xmit_buff_2[2][XMIT_BUFFER_SIZE] = {{XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY, 37 | XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY}, 38 | {XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY, 39 | XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY, XMIT_INFOENTRY_EMPTY}};; 40 | 41 | //No need for double buffering as we directly control parsing 42 | static uint8_t info_codes_rcv_buff[2][RCV_BUFFER_SIZE] = {{RCV_INFOENTRY_EMPTY, RCV_INFOENTRY_EMPTY, RCV_INFOENTRY_EMPTY, 43 | RCV_INFOENTRY_EMPTY, RCV_INFOENTRY_EMPTY, RCV_INFOENTRY_EMPTY}, 44 | {RCV_INFOENTRY_EMPTY, RCV_INFOENTRY_EMPTY, RCV_INFOENTRY_EMPTY, 45 | RCV_INFOENTRY_EMPTY, RCV_INFOENTRY_EMPTY, RCV_INFOENTRY_EMPTY}};; 46 | 47 | static uint8_t xmit_page[2] = {0,0}; 48 | static uint8_t rcvd_pages[2] = {0,0}; 49 | 50 | uint8_t current_rcvd_codes[32] = {0}; 51 | 52 | void copy_buffer(uint8_t source[], uint8_t destination[], uint8_t size) { 53 | uint8_t i, j; 54 | uint8_t index; 55 | size /= 6; //we know size is evenly divisible by 6 56 | 57 | for (i = 0; i < size; i++) { 58 | for (j = 0; j < 6; j++) { 59 | index = i * 6 + j; 60 | destination[index] = source[index]; 61 | } 62 | if (source[index] == XMIT_INFOENTRY_EMPTY) return; 63 | } 64 | } 65 | 66 | bool set_info_code(uint8_t ch, uint8_t code) { 67 | uint8_t i, j; 68 | uint8_t index; 69 | int8_t inserted = -1; 70 | uint8_t size = XMIT_BUFFER_SIZE / 6; //we know size is evenly divisible by 6 71 | 72 | for (i = 0; i < size; i++) { 73 | for (j = 0; j < 6; j++) { 74 | index = i * 6 + j; 75 | if (info_codes_xmit_buff_1[ch][index] == code) return FALSE; 76 | if (inserted >= 0) { 77 | info_codes_xmit_buff_1[ch][index] = XMIT_INFOENTRY_EMPTY; 78 | } else { 79 | if (info_codes_xmit_buff_1[ch][index] == XMIT_INFOENTRY_EMPTY) { 80 | info_codes_xmit_buff_1[ch][index] = code; 81 | inserted = j; 82 | } 83 | } 84 | } 85 | if (inserted == 5) { 86 | inserted = 0; 87 | } else if (inserted >= 0) { 88 | print_info_code_change(ch, MY_ID_BOOL, code, TRUE); 89 | return TRUE; 90 | } 91 | } 92 | return FALSE; //how did we get here? 93 | } 94 | 95 | //Insert at the beginning of the list. Returns false if the code is already in the list. It will be moved to the beginning. 96 | bool set_priority_info_code(uint8_t ch, uint8_t code) { 97 | uint8_t i, j; 98 | uint8_t index; 99 | uint8_t prev = code, curr; 100 | bool end = FALSE; 101 | uint8_t size = XMIT_BUFFER_SIZE / 6; //we know size is evenly divisible by 6 102 | 103 | for (i = 0; i < size; i++) { 104 | for (j = 0; j < 6; j++) { 105 | index = i * 6 + j; 106 | curr = prev; 107 | prev = info_codes_xmit_buff_1[ch][index]; 108 | if ((index != 0) && (curr == code)) return FALSE; 109 | if (curr == XMIT_INFOENTRY_EMPTY) end = TRUE; 110 | info_codes_xmit_buff_1[ch][index] = end ? XMIT_INFOENTRY_EMPTY : curr; 111 | } 112 | if (end) { 113 | print_info_code_change(ch, MY_ID_BOOL, code, PRIORITY); 114 | return TRUE; 115 | } 116 | } 117 | return FALSE; //how did we get here? 118 | } 119 | 120 | bool clear_info_code(uint8_t ch, uint8_t code) { 121 | uint8_t i, j; 122 | uint8_t index; 123 | bool removed = FALSE, end = FALSE; 124 | uint8_t size = XMIT_BUFFER_SIZE / 6; //we know size is evenly divisible by 6 125 | 126 | for (i = 0; i < size; i++) { 127 | for (j = 0; j < 6; j++) { 128 | index = i * 6 + j; 129 | if (info_codes_xmit_buff_1[ch][index] == code) { 130 | print_info_code_change(ch, MY_ID_BOOL, code, FALSE); 131 | removed = TRUE; 132 | } 133 | if (removed) { 134 | if (end) { 135 | info_codes_xmit_buff_1[ch][index] = XMIT_INFOENTRY_EMPTY; 136 | } else { 137 | #pragma MESSAGE DISABLE C5909 //Assignment in condition. Fully intentional 138 | if ((info_codes_xmit_buff_1[ch][index] = info_codes_xmit_buff_1[ch][index + 1]) == XMIT_INFOENTRY_EMPTY) end = TRUE; 139 | } 140 | } 141 | } 142 | if (end) return removed; 143 | } 144 | 145 | return removed; 146 | } 147 | 148 | void clear_all_info_codes(uint8_t ch) { 149 | //Fill the first page with "Empty." Any codes in later pages will be treated as uninitialized memory. 150 | mem_init(info_codes_xmit_buff_1[ch], 6, XMIT_INFOENTRY_EMPTY); 151 | } 152 | 153 | //We must handle empties between valid codes as the standard does not disallow this 154 | void parse_info_codes(uint8_t ch) { 155 | uint8_t i, j; 156 | uint8_t index; 157 | uint8_t size = RCV_BUFFER_SIZE / 6; //we know size is evenly divisible by 6 158 | bool valid_codes = FALSE; 159 | uint8_t new_rcvd_codes[32] = {0}; 160 | uint8_t partial, check_bit; 161 | 162 | #define set_rcvd_code(code) new_rcvd_codes[(code) >> 3] |= (1 << ((code) & 0b00000111)) 163 | 164 | for (i = 0; i < size; i++) { 165 | for (j = 0; j < 6; j++) { 166 | index = i * 6 + j; 167 | if (info_codes_rcv_buff[ch][index] != RCV_INFOENTRY_EMPTY) { 168 | valid_codes = TRUE; 169 | set_rcvd_code(info_codes_rcv_buff[ch][index]); 170 | } 171 | } 172 | if (info_codes_rcv_buff[ch][index] == RCV_INFOENTRY_EMPTY) break; 173 | } 174 | 175 | if (valid_codes) { 176 | for (i = 0; i < 32; i++) { 177 | if ((partial = (new_rcvd_codes[i] ^ current_rcvd_codes[i]))) { 178 | for (j = 0; j < 8; j++) { 179 | check_bit = (1 << j); 180 | if (partial & check_bit) { 181 | if (partial & check_bit & current_rcvd_codes[i]) { 182 | print_info_code_change(ch, !MY_ID_BOOL, ((i << 3) | j), FALSE); 183 | } else{ 184 | print_info_code_change(ch, !MY_ID_BOOL, ((i << 3) | j), TRUE); 185 | } 186 | } 187 | } 188 | } 189 | } 190 | } 191 | 192 | mem_copy(new_rcvd_codes, current_rcvd_codes, 32); 193 | } 194 | 195 | void xmit_info_code_page(uint8_t ch) { 196 | if (xmit_page[ch] == 0) { 197 | copy_buffer(info_codes_xmit_buff_1[ch], info_codes_xmit_buff_2[ch], XMIT_BUFFER_SIZE); 198 | } 199 | 200 | #pragma MESSAGE DISABLE C2705 //possible loss of data.is this the flags again? FIXME 201 | LW(ch, l_u8, XMIT_INFO(PageNumber), xmit_page[ch]); 202 | #pragma MESSAGE DISABLE C2705 //possible loss of data.is this the flags again? FIXME 203 | LW(ch, l_u8, XMIT_INFO(Entry1), info_codes_xmit_buff_2[ch][xmit_page[ch] * 6]); 204 | #pragma MESSAGE DISABLE C2705 //possible loss of data.is this the flags again? FIXME 205 | LW(ch, l_u8, XMIT_INFO(Entry2), info_codes_xmit_buff_2[ch][xmit_page[ch] * 6 + 1]); 206 | #pragma MESSAGE DISABLE C2705 //possible loss of data.is this the flags again? FIXME 207 | LW(ch, l_u8, XMIT_INFO(Entry3), info_codes_xmit_buff_2[ch][xmit_page[ch] * 6 + 2]); 208 | #pragma MESSAGE DISABLE C2705 //possible loss of data.is this the flags again? FIXME 209 | LW(ch, l_u8, XMIT_INFO(Entry4), info_codes_xmit_buff_2[ch][xmit_page[ch] * 6 + 3]); 210 | #pragma MESSAGE DISABLE C2705 //possible loss of data.is this the flags again? FIXME 211 | LW(ch, l_u8, XMIT_INFO(Entry5), info_codes_xmit_buff_2[ch][xmit_page[ch] * 6 + 4]); 212 | #pragma MESSAGE DISABLE C2705 //possible loss of data.is this the flags again? FIXME 213 | LW(ch, l_u8, XMIT_INFO(Entry6), info_codes_xmit_buff_2[ch][xmit_page[ch] * 6 + 5]); 214 | 215 | if (info_codes_xmit_buff_2[ch][(++xmit_page[ch]) * 6 - 1] == XMIT_INFOENTRY_EMPTY) xmit_page[ch] = 0; 216 | 217 | //clear flag 218 | LFC(ch, XMIT_INFO(List)); 219 | } 220 | 221 | void rcv_info_code_page(uint8_t ch) { 222 | uint8_t rcv_page = LR(ch, l_u8, RCV_INFO(PageNumber)); 223 | 224 | rcvd_pages[ch]++; 225 | if (rcv_page == 0) rcvd_pages[ch] = 1; //make sure we can resynchronize 226 | 227 | if (!(rcv_page * 6 > RCV_BUFFER_SIZE)) { //don't overflow the buffer 228 | info_codes_rcv_buff[ch][rcv_page * 6] = LR(ch, l_u8, RCV_INFO(Entry1)); 229 | info_codes_rcv_buff[ch][rcv_page * 6 + 1] = LR(ch, l_u8, RCV_INFO(Entry2)); 230 | info_codes_rcv_buff[ch][rcv_page * 6 + 2] = LR(ch, l_u8, RCV_INFO(Entry3)); 231 | info_codes_rcv_buff[ch][rcv_page * 6 + 3] = LR(ch, l_u8, RCV_INFO(Entry4)); 232 | info_codes_rcv_buff[ch][rcv_page * 6 + 4] = LR(ch, l_u8, RCV_INFO(Entry5)); 233 | info_codes_rcv_buff[ch][rcv_page * 6 + 5] = LR(ch, l_u8, RCV_INFO(Entry6)); 234 | } 235 | 236 | if ((rcv_page + 1 == rcvd_pages[ch]) && (info_codes_rcv_buff[ch][rcv_page * 6 + 5] == RCV_INFOENTRY_EMPTY)) { 237 | parse_info_codes(ch); 238 | rcvd_pages[ch] = 0; 239 | } 240 | 241 | //clear flag 242 | LFC(ch, RCV_INFO(List)); 243 | } 244 | 245 | // >IA:::(:)(#Comment) 246 | // >IA:E:19:C#Internal Fault 247 | void print_info_code_change(uint8_t ch, uint8_t id, uint8_t code, uint8_t op){ //id TRUE->SE, FALSE->EV; op 0->clear, 1-> set, 2->priority set (local only) 248 | int8_t xmit_buffer1[] = ">IA:X:"; 249 | #ifdef CH_A_ONLY 250 | int8_t xmit_buffer2[] = ":Y#"; 251 | #else 252 | int8_t xmit_buffer2[] = ":Y:Z#"; 253 | #endif 254 | 255 | xmit_buffer1[4] = id ? 'S' : 'E'; 256 | xmit_buffer2[1] = op ? ((op == 2) ? 'P': 'S') : 'C'; 257 | 258 | #ifndef CH_A_ONLY 259 | xmit_buffer2[3] = ch ? 'B' : 'A'; 260 | #endif 261 | 262 | PrintCmdsString( (char *) xmit_buffer1,0); 263 | PrintCmdsHex(code); 264 | PrintCmdsString(xmit_buffer2,0); 265 | if (id) { 266 | PrintCmdsString((signed char *const)(SE_Info_Codes[code]),0); 267 | } else { 268 | PrintCmdsString((signed char *const)(EV_Info_Codes[code]),0); 269 | } 270 | PrintCmdsString("\r\n",0); 271 | } 272 | 273 | //We must handle empties between valid codes as the standard does not disallow this 274 | void print_all_info_codes_int(uint8_t ch, uint8_t id, uint8_t * buffer, uint8_t buffer_size) { 275 | uint8_t i, j; 276 | uint8_t index; 277 | uint8_t size = buffer_size / 6; //we know size is evenly divisible by 6 278 | bool valid_codes = FALSE; 279 | 280 | for (i = 0; i < size; i++) { 281 | for (j = 0; j < 6; j++) { 282 | index = i * 6 + j; 283 | if (buffer[index] != RCV_INFOENTRY_EMPTY) { 284 | if (!valid_codes) { 285 | PrintConsoleString("Set ", 0); 286 | if (id) { 287 | PrintConsoleString("SE", 0); 288 | } else{ 289 | PrintConsoleString("EV", 0); 290 | } 291 | PrintConsoleString(" Channel:", 0); 292 | PrintConsoleChar(ch? 'B': 'A'); 293 | PrintConsoleString(" Codes:\r\n", 0); 294 | valid_codes = TRUE; 295 | } 296 | PrintConsoleString("\t", 0); 297 | PrintConsoleHex(buffer[index]); 298 | PrintConsoleString("\t", 0); 299 | if (id) { 300 | PrintConsoleString((signed char *const)(SE_Info_Codes[buffer[index]]),0); 301 | } else { 302 | PrintConsoleString((signed char *const)(EV_Info_Codes[buffer[index]]),0); 303 | } 304 | PrintConsoleString("\r\n", 0); 305 | } 306 | } 307 | if (buffer[index] == RCV_INFOENTRY_EMPTY) break; 308 | } 309 | if (valid_codes) PrintConsoleString("\r\n", 0); 310 | #pragma MESSAGE DISABLE C12056 //debug info incorrect because of optimization or inline assembler 311 | } 312 | 313 | void print_all_info_codes(uint8_t ch) { 314 | print_all_info_codes_int(ch, MY_ID_BOOL, &(info_codes_xmit_buff_2[ch][0]), XMIT_BUFFER_SIZE); 315 | print_all_info_codes_int(ch, !MY_ID_BOOL, &(info_codes_rcv_buff[ch][0]), RCV_BUFFER_SIZE); 316 | } 317 | 318 | #pragma INLINE 319 | bool check_remote_code(uint8_t code) { 320 | return !!(current_rcvd_codes[code >> 3] & (1 << (code & 0b00000111))); 321 | } 322 | -------------------------------------------------------------------------------- /Project/Sources/info_code_handler.h: -------------------------------------------------------------------------------- 1 | #ifndef _INFO_CODE_HANDLER_H 2 | #define _INFO_CODE_HANDLER_H 3 | 4 | bool set_info_code(uint8_t ch, uint8_t code); 5 | bool set_priority_info_code(uint8_t ch, uint8_t code); 6 | bool clear_info_code(uint8_t ch, uint8_t code); 7 | void clear_all_info_codes(uint8_t ch); 8 | 9 | void xmit_info_code_page(uint8_t ch); 10 | void rcv_info_code_page(uint8_t ch); 11 | 12 | void print_info_code_change(uint8_t ch, uint8_t id, uint8_t code, uint8_t op); //id TRUE->SE, FALSE->EV; op 0->clear, 1-> set, 2->priority set (local only) 13 | void print_all_info_codes(uint8_t ch); 14 | 15 | bool check_remote_code(uint8_t code); 16 | 17 | #define PRIORITY 2 18 | 19 | #endif -------------------------------------------------------------------------------- /Project/Sources/interrupts.c: -------------------------------------------------------------------------------- 1 | #include "derivative.h" 2 | #include "lin.h" 3 | #include "types.h" 4 | #include "globals.h" 5 | #include "sci.h" 6 | #include "timers.h" 7 | #include "hardware.h" 8 | #include "scheduler.h" 9 | #include "pilot.h" 10 | #include "lin-cp.h" 11 | #include "j1939.h" 12 | 13 | #pragma CODE_SEG __NEAR_SEG NON_BANKED 14 | 15 | static uint8_t timeoutcounterA, timeoutcounterB; 16 | 17 | /******************************************************* 18 | * timebase timer interrupt 19 | ********************************************************/ 20 | 21 | interrupt VectorNumber_Vtimer6 void TIM_TIMER6_ISR(void) { 22 | static l_u8 timebase_counter =0; 23 | if (timebase_counter>=20){ 24 | timebase_flag = TRUE; 25 | timebase_counter = 0; 26 | } 27 | timebase_counter++; 28 | /* Clear timer flag */ 29 | TFLG1_C6F = 1; //clear timer 6 interrupt flag (set bit to clear it because reasons pg. 750) 30 | /* Reset timer counter */ 31 | TC6 = (TC6 + TIMER_6_PERIOD) &0xFFFF; 32 | } 33 | 34 | /******************************************************* 35 | * Analog sample timeout timer interrupt 36 | ********************************************************/ 37 | 38 | interrupt VectorNumber_Vtimer1 void TIM_TIMER1_ISR(void) { 39 | uint8_t sample; 40 | 41 | if (PILOTA_WAKEUP_INTERRUPT_ENABLE == ON){ //no PWM is detected in an appropriate period 42 | timeoutcounterA++; 43 | timeoutcounterA %= 5; 44 | if (timeoutcounterA == 0 || !InLINState(A)) { //make timeout 5 times longer when in LIN to account for larger gaps. 45 | //DEBUG4 = ! DEBUG4; 46 | sample = PilotAReadADC(); 47 | Pilot_Voltage_Filter_Add(A, sample); //positive and negative the same as signal not changing 48 | Pilot_Voltage_Neg_Filter_Add(A, sample); 49 | 50 | #ifdef EV_CONFIG //set period and duty cycle to "invalid" 51 | Pilot_Period_Filter_Add(A, (Pilot_Voltage[A] == STATE_E)? 0 : 100); 52 | Pilot_Duty_Cycle_Filter_Add(A, 0 ); 53 | #endif 54 | 55 | PILOTA_WAKEUP_INTERRUPT_ENABLE = OFF; 56 | } 57 | } 58 | 59 | if (PILOTB_WAKEUP_INTERRUPT_ENABLE == ON){ //no PWM is detected in an appropriate period 60 | timeoutcounterB++; 61 | timeoutcounterB %= 5; 62 | if (timeoutcounterB == 0 || !InLINState(B)) { //make timeout 5 times longer when in LIN to account for larger gaps. 63 | sample = PilotBReadADC(); 64 | Pilot_Voltage_Filter_Add(B, sample); //positive and negative the same as signal not changing 65 | Pilot_Voltage_Neg_Filter_Add(B, sample); 66 | 67 | #ifdef EV_CONFIG //set period and duty cycle to "invalid" 68 | Pilot_Period_Filter_Add(B, (Pilot_Voltage[B] == STATE_E)? 0 : 100); 69 | Pilot_Duty_Cycle_Filter_Add(B, 0 ); 70 | #endif 71 | 72 | PILOTB_WAKEUP_INTERRUPT_ENABLE = OFF; 73 | } 74 | } 75 | TFLG1_C1F = 1; //clear timer 1 interrupt flag (set bit to clear it because reasons pg. 750) 76 | /* Reset timer counter */ 77 | timer_1_reset(); 78 | } 79 | 80 | /******************************************************* 81 | * Real Time Interrupt (RTI) 82 | ********************************************************/ 83 | 84 | interrupt VectorNumber_Vrti void RTI_ISR(void){ 85 | static uint8_t PilotSample = 0, ProxSample = 0, LINState = 0; 86 | 87 | #ifdef EV_CONFIG 88 | DetermineEvState(A,NO_CODE); 89 | #ifndef CH_A_ONLY 90 | DetermineEvState(B,NO_CODE); 91 | #endif 92 | //process_plug_state(); 93 | #endif 94 | 95 | #ifdef SE_CONFIG 96 | DetermineEvseState(A, NO_CODE); 97 | #ifndef CH_A_ONLY 98 | DetermineEvseState(B, NO_CODE); 99 | #endif 100 | #endif 101 | 102 | /*******************/ 143 | 144 | /*******************/ 156 | 157 | /*******************/ 178 | 179 | update_delay_count(); // tick scheduler 180 | __RTIF = 1; // Clear RTIF 181 | } 182 | 183 | /******************************************************* 184 | * Port P Edge Detect 185 | ********************************************************/ 186 | 187 | interrupt VectorNumber_Vportp void PORTP_ISR(void){ 188 | static uint8_t secondA = 0; 189 | static uint8_t secondB = 0; 190 | 191 | static uint16_t rising_edge_timeA = 0, last_rising_edge_timeA = 0; 192 | static uint16_t cycle_timeA, high_timeA; 193 | 194 | static uint16_t rising_edge_timeB = 0, last_rising_edge_timeB = 0; 195 | static uint16_t cycle_timeB, high_timeB; 196 | 197 | if (PILOTA_WAKEUP_INTERRUPT_ENABLE && PILOTA_WAKEUP_INTERRUPT_FLAG) { 198 | if(PILOTA_WAKEUP_INTERRUPT_POLARITY){ //rising edge detected 199 | PILOTA_WAKEUP_INTERRUPT_POLARITY = 0; 200 | timer_1_reset(); rising_edge_timeA = TCNT; 201 | timeoutcounterA = 0; 202 | if(secondA){ 203 | //RisingAEdgeRoutine(); 204 | cycle_timeA = rising_edge_timeA - last_rising_edge_timeA; //calculate PWM period in terms of bus clocks 205 | DelayUs(EDGE_BACKOFF_TIME_US); //shift sample from edge to account for capacitance on the line 206 | //DEBUG2 = 1; 207 | Pilot_Voltage_Filter_Add(A,PilotAReadADC()); 208 | //DEBUG2 = 0; 209 | #ifdef EV_CONFIG 210 | Pilot_Period_Filter_Add(A, (cycle_timeA > (MCU_BUS_FREQ/1040)) && (cycle_timeA < (MCU_BUS_FREQ/960))); //double tolerance from standard to account for error on both sides 211 | Pilot_Duty_Cycle_Filter_Add(A, (uint8_t) ((100 * (uint32_t) (high_timeA + (MCU_BUS_FREQ/200000) ))/cycle_timeA)); //add a nominal 0.5% to round correctly (MCU_BUS_FREQ/1000*0.005) 212 | #endif 213 | secondA = 0; 214 | PILOTA_WAKEUP_INTERRUPT_ENABLE = OFF; //turn it off - we should be done 215 | } 216 | last_rising_edge_timeA = rising_edge_timeA; 217 | } 218 | else { 219 | PILOTA_WAKEUP_INTERRUPT_POLARITY = 1; 220 | high_timeA = TCNT - last_rising_edge_timeA; //must be before backoff time 221 | DelayUs(EDGE_BACKOFF_TIME_US); 222 | //DEBUG3 = 0; 223 | Pilot_Voltage_Neg_Filter_Add(A, PilotAReadADC()); 224 | //DEBUG3 = 1; 225 | secondA = 1; 226 | } 227 | } 228 | 229 | #ifndef CH_A_ONLY 230 | if (PILOTB_WAKEUP_INTERRUPT_ENABLE && PILOTB_WAKEUP_INTERRUPT_FLAG) { 231 | if(PILOTB_WAKEUP_INTERRUPT_POLARITY){ //rising edge detected 232 | PILOTB_WAKEUP_INTERRUPT_POLARITY = 0; 233 | timer_1_reset(); rising_edge_timeB = TCNT; 234 | timeoutcounterB = 0; 235 | if(secondB){ 236 | //RisingBEdgeRoutine(); 237 | cycle_timeB = rising_edge_timeB - last_rising_edge_timeB; //calculate PWM period in terms of bus clocks 238 | DelayUs(EDGE_BACKOFF_TIME_US); //shift sample from edge to account for capacitance on the line 239 | //DEBUG2 = 1; 240 | Pilot_Voltage_Filter_Add(B, PilotBReadADC()); 241 | //DEBUG2 = 0; 242 | #ifdef EV_CONFIG 243 | Pilot_Period_Filter_Add(B, (cycle_timeB > (MCU_BUS_FREQ/1040)) && (cycle_timeB < (MCU_BUS_FREQ/960))); //double tolerance from standard to account for error on both sides 244 | Pilot_Duty_Cycle_Filter_Add(B, (uint8_t) ((100 * (uint32_t) (high_timeB + (MCU_BUS_FREQ/200000) ))/cycle_timeB)); //add a nominal 0.5% to round correctly (MCU_BUS_FREQ/1000*0.005) 245 | #endif 246 | secondB = 0; 247 | PILOTB_WAKEUP_INTERRUPT_ENABLE = OFF; //turn it off - we should be done 248 | } 249 | last_rising_edge_timeB = rising_edge_timeB; 250 | } 251 | else { 252 | PILOTB_WAKEUP_INTERRUPT_POLARITY = 1; 253 | high_timeB = TCNT - last_rising_edge_timeB; //must be before backoff time 254 | DelayUs(EDGE_BACKOFF_TIME_US); 255 | //DEBUG3 = 0; 256 | Pilot_Voltage_Neg_Filter_Add(B, PilotBReadADC()); 257 | //DEBUG3 = 1; 258 | secondB = 1; 259 | } 260 | } 261 | #endif 262 | PIFP = 0xFF; // Clear all Port P interrupts 263 | } 264 | 265 | /******************************************************* 266 | * Serial Communication Interrupt 267 | ********************************************************/ 268 | 269 | interrupt VectorNumber_Vsci2 void SCI2_ISR(void){ 270 | uint8_t rcv; 271 | 272 | //PTP_PTP4 = !PTP_PTP4; 273 | 274 | if(SCI2SR1_RDRF){ 275 | rcv = SCI2DRL; 276 | SCI_RXRoutine(rcv); 277 | } 278 | 279 | if(SCI2SR1_TDRE){ 280 | if (print_buf.inpos == print_buf.outpos){ // buffer empty 281 | SCI2CR2_TIE = 0; // disable transmit interrupts 282 | } 283 | else{ 284 | SCI2DRL = print_buf.data[print_buf.outpos]; 285 | (void)CBufPop(&print_buf); 286 | } 287 | } 288 | 289 | if(SCI2ASR1_RXEDGIF) SCI2ASR1_RXEDGIF=1; 290 | 291 | if (SCI2SR1 & (SCI2SR1_OR_MASK | SCI2SR1_NF_MASK | SCI2SR1_FE_MASK)) 292 | rcv = SCI2DRL; //acknowledge noise, framing, and overflow errors 293 | } 294 | 295 | /******************************************************* 296 | * Controller Area Network Interrupt (CAN) 297 | ********************************************************/ 298 | 299 | interrupt VectorNumber_Vcan0rx void CAN0RX_ISR(void){ 300 | //PrintConsoleString("CAN Rx\r\n", 0); 301 | CAN0_RXRoutine(); 302 | CAN0RFLG |= 1; // clear RXF flag 303 | } 304 | 305 | interrupt VectorNumber_Vcan0wkup void CAN0WKUP_ISR(void){ 306 | CAN0RFLG_WUPIF = 1; 307 | } 308 | 309 | #pragma CODE_SEG DEFAULT /* Return to default code segment */ -------------------------------------------------------------------------------- /Project/Sources/j1939.h: -------------------------------------------------------------------------------- 1 | #ifndef __J1939_H__ 2 | #define __J1939_H__ 3 | 4 | #include "types.h" 5 | 6 | #include "pilot.h" 7 | #include "hardware.h" 8 | #include "j1939-signals.h" 9 | 10 | void CAN0_RXRoutine(void); 11 | 12 | #define CAN_ID_PTRN_1 J1939_ID_HSC1 | (J1939_CHANNEL_A_INLET_ID << 8) | J1939_ECU_ID //HSC1 13 | #define CAN_MASK_PTRN_1 0 14 | #ifdef CH_A_ONLY 15 | #define CAN_ID_PTRN_2 (J1939_ID_HSS1 & J1939_ID_EVSE1AC3PL) | (J1939_ECU_ID & J1939_CHANNEL_A_INVERTER_ID) //HSS1 and EVSE1AC3PL 16 | #define CAN_MASK_PTRN_2 (J1939_ID_HSS1 ^ J1939_ID_EVSE1AC3PL) 17 | #else 18 | #define CAN_ID_PTRN_2 (J1939_ID_HSS1 & J1939_ID_EVSE1AC3PL) | (J1939_ECU_ID & J1939_CHANNEL_A_INVERTER_ID & J1939_CHANNEL_B_INVERTER_ID) //HSS1 and EVSE1AC3PL for each channel 19 | #define CAN_MASK_PTRN_2 (J1939_ID_HSS1 ^ J1939_ID_EVSE1AC3PL) | ((J1939_ECU_ID ^ J1939_CHANNEL_A_INVERTER_ID) | \ 20 | (J1939_ECU_ID ^ J1939_CHANNEL_B_INVERTER_ID)) 21 | #endif 22 | 23 | typedef enum { 24 | EV_MODE_UNKNOWN = 0x00, 25 | EV_MODE_CHARGE = 0x01, 26 | EV_MODE_V2G = 0x02, 27 | EV_MODE_ERROR = 0x03, 28 | EV_MODE_STOP = 0x04, 29 | EV_MODE_DRIVE = 0x05, 30 | } ev_mode_t; 31 | 32 | enum { 33 | CAN_INIT_MSG_OPCODE, 34 | CAN_INIT_MSG_KIND, 35 | CAN_INIT_MSG_TYPE, 36 | CAN_INIT_MSG_VERSION, 37 | CAN_INIT_MSG_DEBUG_FLAGS, 38 | CAN_INIT_MSG_SIZE 39 | }; 40 | 41 | enum can_offsets { 42 | CAN_OFFSET_ID0 = 0, 43 | CAN_OFFSET_ID1 = 1, 44 | CAN_OFFSET_DATA = 4, 45 | CAN_OFFSET_MSG_LEN = 12 46 | }; 47 | 48 | enum can_ids { 49 | CAN_ID_STATION_STATUS = 0x181, 50 | CAN_ID_EV_STATUS = 0x182, 51 | 52 | CAN_ID_INBAND_DATA = 0x2C0, 53 | 54 | CAN_ID_PPP1 = 0x481, 55 | CAN_ID_PPP2 = 0x482, 56 | }; 57 | 58 | enum can_ops { 59 | CAN_PARAM_REQUEST = 0x01, 60 | CAN_PARAM_ACK = 0x02, 61 | CAN_PARAM_NACK = 0x03, 62 | 63 | CAN_OP_INIT = 0xA0, 64 | CAN_OP_MAX_RATES = 0xC0, 65 | CAN_OP_EVSE_EV_CMD = 0xC1, 66 | CAN_OP_EV_EVSE_CMD = 0xC2, 67 | CAN_OP_EVSE_STATUS = 0xC3, 68 | CAN_OP_EV_STATUS = 0xC4, 69 | CAN_OP_OEM_STATUS = 0xC5, 70 | CAN_OP_ID_DESC = 0xC6, 71 | CAN_OP_ID_DATA = 0xC7, 72 | CAN_OP_ARBITRARY_DATA = 0xC8, 73 | CAN_OP_REQUEST_DEBUG_INFO = 0xC9, 74 | CAN_OP_SET_DEBUG_VAR = 0xCA, 75 | CAN_OP_DEBUG_DATA = 0xCB, 76 | 77 | CAN_OP_OEM_ERROR = 0xCE, 78 | CAN_OP_DISABLE_PWM = 0xCF, 79 | }; 80 | 81 | enum can_data_keys { 82 | CAN_KEY_V12BATT = 0x0001, 83 | CAN_KEY_TOTAL_NUMBER_OF_DEFINED_KEYS, 84 | }; 85 | 86 | typedef struct { 87 | EVSE1ACS1_t EVSE1ACS1_A; 88 | EVSE1ACS1_t EVSE1ACS1_B; 89 | HSI1_t HSI1; 90 | EVSE1S1_t EVSE1S1_A; 91 | EVSE1S1_t EVSE1S1_B; 92 | EVSE1ACSV_t EVSE1ACSV_A; 93 | EVSE1ACSV_t EVSE1ACSV_B; 94 | InletProxAndSeInfo_t ProxSEInfo_A; 95 | InletProxAndSeInfo_t ProxSEInfo_B; 96 | HSC1_t HSC1; 97 | } j1939_messages_to_send_t; 98 | 99 | typedef struct { 100 | HSC1_t HSC1_A; 101 | HSC1_t HSC1_B; 102 | HSS1_t HSS1; 103 | EVSE1AC3PL_t EVSE1AC3PL_A; 104 | EVSE1AC3PL_t EVSE1AC3PL_B; 105 | } j1939_messages_received_t; 106 | 107 | void j1939_init_hardware(void); 108 | void send_j1939_messages(void); 109 | void populate_j1939_messages(void); 110 | 111 | #endif // HEADER GUARD 112 | -------------------------------------------------------------------------------- /Project/Sources/j3072_handler.h: -------------------------------------------------------------------------------- 1 | #ifndef J3072_HANDLER_H 2 | #define J3072_HANDLER_H 3 | 4 | enum {CERT_INCOMPLETE = 0, CERT_COMPLETE, SUNSPEC}; 5 | 6 | bool cert_parse(uint8_t ch); 7 | void cert_xmit(uint8_t ch, uint8_t page); 8 | 9 | void j3072_init(uint8_t ch); 10 | void on_j3072_frame_receipt(uint8_t ch); 11 | void on_j3072_frame_xmit(uint8_t ch); 12 | 13 | 14 | #endif -------------------------------------------------------------------------------- /Project/Sources/lin-cp.h: -------------------------------------------------------------------------------- 1 | #ifndef LIN_CP_H 2 | #define LIN_CP_H 3 | 4 | #include "derivative.h" 5 | #include "hardware.h" 6 | #include "pilot.h" 7 | #include "lin.h" 8 | #include "lin_cfg.h" 9 | #include "types.h" 10 | 11 | #define LIN_DETECT_TIMEOUT 2000 12 | 13 | typedef enum {StartNull, RunNull, StartVer, RunVer, StartInit, RunInit, StartOp, RunOp, 14 | StartErr, RunErr, StartSleep, RunSleep} SCHEDULE_PICKER; 15 | 16 | typedef enum {continueOnLIN, startLIN, stopLIN} SCHEDULE_PICKER_EVENTS; 17 | 18 | void InitializeLINCP(void); 19 | void DetermineLINCPState(uint8_t ch, SCHEDULE_PICKER_EVENTS SchedulePickerMessage); 20 | 21 | void PrintLinCPStatus(uint8_t ch); 22 | 23 | #define EMPTY 24 | #define LV(t,rw,it,v,a) t##_##rw##_##it##_##v(a) 25 | #define LF(tc,it,v) l_flg_##tc##_##it##_##v##_flag() 26 | #define LS(it,sch,a) l_sch_set(it,it##_##sch,a) 27 | #define LW(it,t,v,a) if (it) {LV(t,wr,LI1,v,a);} else {LV(t,wr,LI0,v,a);} 28 | #define LR(it,t,v) ( (it) ? LV(t,rd,LI1,v,EMPTY): LV(t,rd,LI0,v,EMPTY) ) 29 | #define LFT(it,v) ( (it) ? LF(tst,LI1,v): LF(tst,LI0,v) ) 30 | #define LFC(it,v) if (it) {LF(clr,LI1,v);} else {LF(clr,LI0,v);} 31 | #define LSS(it,sch,a) if (it) {LS(LI1,sch,a);} else {LS(LI0,sch,a);} 32 | 33 | //If single phase, use the "t" value, else use the "f" value. "t" value should be 0 or the type-appropriate Not Available value as needed. 34 | #if defined(TYPE_I_COUPLER) || defined(SINGLE_PHASE) 35 | #define SP(f,t) (t) 36 | #else 37 | #define SP(f,t) (f) 38 | #endif 39 | 40 | 41 | #define RTI_TICKS_PER_LINCP_LOOP 20 // How often the LIN-CP state machine is serviced 42 | 43 | //9.3 -- Table 16 --- updated to SAE J3068 202207 May 9, 23 44 | #define T_SESTART RTI_TICKS_PER_SECOND/2 // R#:9.4.1.2 SE max time to start LIN Schedule 45 | #define T_EVSTART 1*RTI_TICKS_PER_SECOND // R#:9.4.1.3 EV max time to start responding 46 | #define T_PWM (1*RTI_TICKS_PER_SECOND\ 47 | +RTI_TICKS_PER_SECOND/10) // R#:9.5.4.1 SE max time to establish LIN-CP 48 | #define T_EVCLOSE 3*RTI_TICKS_PER_SECOND // R#:9.7.2.4 EV max time to close S2 49 | #define T_SECLOSE 3*RTI_TICKS_PER_SECOND // R#:9.7.2.5 SE max time to close the Contactor 50 | #define T_GLITCH 1*RTI_TICKS_PER_SECOND // R#:9.7.2.6 R#:9.7.2.7 SE or EV time to ignore CP level glitch 51 | // R#:9.7.2.8 R#:10.8.5.2 EV time to ignore prox voltage or lock glitch 52 | #define T_SEADAPT 10*RTI_TICKS_PER_SECOND // R#:9.7.3.2 SE max time to adapt SeAvailableCurrents to external limit (for example, energy management system) 53 | #define T_EVADAPT 5*RTI_TICKS_PER_SECOND // R#:9.7.3.6 EV max time to adapt load current to SeAvailableCurrents 54 | #define T_SEOPEN 3*RTI_TICKS_PER_SECOND // R#:9.7.4.2 R#:10.7.2.2 SE max time to open the Contactor 55 | #define T_RAMPDOWN 6*RTI_TICKS_PER_SECOND // R#:9.7.5.1 R#:10.2.1.1 SE min time to wait before interrupting supply 56 | #define T_EVOPEN 3*RTI_TICKS_PER_SECOND // R#:9.7.5.2 R#:10.7.1.1 EV max time to open S2 57 | #define T_UNLOCK 3*RTI_TICKS_PER_SECOND // R#:9.8.1.1 R#:9.8.2.2 EV max time to unlock Inlet 58 | #define T_VER 5*RTI_TICKS_PER_SECOND // R#:10.3.1.1 R#:10.3.2.1 SE and EV timeout before Version selection fails 59 | #define T_INIT 5*RTI_TICKS_PER_SECOND // R#:10.4.1.1 R#:10.4.2.1 SE and EV timeout before initialization fails 60 | #define T_NOLIN 2*RTI_TICKS_PER_SECOND // R#:10.7.1.1 R#:10.7.1.2 EV min time to wait before opening S2, no LIN Headers 61 | // R#:10.7.2.1 R#:10.7.2.2 SE min time to wait before opening the Contactor, no LIN Responses 62 | #define T_SE_12 RTI_TICKS_PER_SECOND/10 // R#:10.8.4.1 SE max time to open the Contactor, SE detects CP Level 12 63 | #define T_EV_unlocked RTI_TICKS_PER_SECOND/10 // R#:10.8.5.1 EV max time to stop drawing current if unexpectedly unlocked. 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /Project/Sources/lock.c: -------------------------------------------------------------------------------- 1 | #include "lock.h" 2 | #include "hardware.h" 3 | #include "scheduler.h" 4 | #include "derivative.h" 5 | #include "types.h" 6 | #include "sci.h" 7 | #include "globals.h" 8 | #include "config.h" 9 | 10 | // 0 for locked and 1 for undefined 11 | 12 | static lock_status_t lockStatus[2] = {unknown, unknown}; 13 | static bool statusMismatch[2] = {FALSE, FALSE}; 14 | 15 | //////////////////////////////////////////////////// 16 | // Status Functions 17 | //////////////////////////////////////////////////// 18 | #pragma INLINE 19 | lock_status_t getLockStatus(uint8_t ch) { 20 | //PrintConsoleString("Lock status is ", 0); 21 | //PrintConsoleHex(lockStatus[ch]); 22 | //PrintConsoleString("\r\n", 0); 23 | return lockStatus[ch]; 24 | } 25 | 26 | #pragma INLINE 27 | bool getIsLocked(uint8_t ch) { 28 | return (lockStatus[ch] == locked) || (lockStatus[ch] == presumedLocked); 29 | } 30 | 31 | #if INLET_LOCK_TYPE == NONE 32 | 33 | #pragma INLINE 34 | lock_status_t getAndVerifyLockStatus(uint8_t ch) { 35 | return lockStatus[ch]; 36 | } 37 | #endif 38 | 39 | #if INLET_LOCK_TYPE == FOUR_WIRE 40 | lock_status_t getAndVerifyLockStatus(uint8_t ch) { 41 | switch(lockStatus[ch]) { 42 | case locking: 43 | case unlocking: 44 | //PrintConsoleString("--\r\n",0); 45 | return lockStatus[ch]; 46 | break; //technically reduncant 47 | case locked: 48 | case presumedLocked: 49 | if (getSenseSignalValue(ch)) { //is unlocked 50 | PrintConsoleString("Channel ",0); 51 | PrintConsoleChar( ch? 'B': 'A' ); 52 | PrintConsoleString(" unexpectedly UNLOCKED\r\n",0); 53 | lockStatus[ch] = presumedUnlocked; 54 | statusMismatch[ch] = TRUE; 55 | } 56 | return lockStatus[ch]; 57 | break; 58 | case unlocked: 59 | case presumedUnlocked: 60 | if (!getSenseSignalValue(ch)) { //is locked 61 | PrintConsoleString("Channel ",0); 62 | PrintConsoleChar( ch? 'B': 'A' ); 63 | PrintConsoleString(" unexpectedly LOCKED\r\n",0); 64 | lockStatus[ch] = locked; 65 | statusMismatch[ch] = TRUE; 66 | } 67 | return lockStatus[ch]; 68 | break; 69 | } 70 | return lockStatus[ch]; 71 | } 72 | #endif 73 | 74 | uint32_t verifyLockAStatus(void *a) { 75 | (void)getAndVerifyLockStatus(A); 76 | return LOCK_CHECK_DELAY; 77 | } 78 | 79 | uint32_t verifyLockBStatus(void *a) { 80 | (void)getAndVerifyLockStatus(B); 81 | return LOCK_CHECK_DELAY; 82 | } 83 | 84 | #pragma INLINE 85 | bool getLockStatusMismatch(uint8_t ch) { 86 | return statusMismatch[ch]; 87 | } 88 | 89 | //////////////////////////////////////////////////// 90 | // Functions to set pins 91 | //////////////////////////////////////////////////// 92 | void startDrivingLock(uint8_t ch) { 93 | lockStatus[ch] = locking; 94 | // Forward 95 | // IN1, IN3 1 96 | // IN2, IN4 0 97 | if (!ch) { 98 | RELAY_CONTROL_A_PLUS = 1; 99 | RELAY_CONTROL_A_MINUS = 0; 100 | } else { 101 | RELAY_CONTROL_B_PLUS = 1; 102 | RELAY_CONTROL_B_MINUS = 0; 103 | } 104 | } 105 | 106 | void startDrivingUnlock(uint8_t ch) { 107 | lockStatus[ch] = unlocking; 108 | // Reverse 109 | // IN1, IN3 0 110 | // IN2, IN4 1 111 | if (!ch) { 112 | RELAY_CONTROL_A_PLUS = 0; 113 | RELAY_CONTROL_A_MINUS = 1; 114 | } else { 115 | RELAY_CONTROL_B_PLUS = 0; 116 | RELAY_CONTROL_B_MINUS = 1; 117 | } 118 | } 119 | 120 | uint32_t endDrivingA(void *a) { 121 | // Coast 122 | RELAY_CONTROL_A_PLUS = 0; 123 | RELAY_CONTROL_A_MINUS = 0; 124 | 125 | return 0; 126 | } 127 | 128 | uint32_t endDrivingB(void *a) { 129 | // Coast 130 | RELAY_CONTROL_B_PLUS = 0; 131 | RELAY_CONTROL_B_MINUS = 0; 132 | 133 | return 0; 134 | } 135 | 136 | #define endDriving(ch) ((ch) ? endDrivingB : endDrivingA) 137 | 138 | //////////////////////////////////////////////////// 139 | // Presumed Functions 140 | //////////////////////////////////////////////////// 141 | 142 | uint32_t setPresumedLockedA(void *a) { 143 | // if locked 144 | if (!UC_SENSE_SIGNAL_A_LOCK) { 145 | lockStatus[A] = locked; 146 | statusMismatch[A] = FALSE; 147 | PrintConsoleString("Successfully locked A\r\n", 0); 148 | } else { 149 | PrintConsoleString("Retrying to lock A\r\n", 0); 150 | schedule_and_reset(RETRY_DELAY, retryLockA, NULL); 151 | } 152 | return 0; 153 | } 154 | 155 | uint32_t setPresumedLockedB(void *a) { 156 | // if locked 157 | if (!UC_SENSE_SIGNAL_B_LOCK) { 158 | lockStatus[B] = locked; 159 | statusMismatch[B] = FALSE; 160 | PrintConsoleString("Successfully locked B\r\n", 0); 161 | } else { 162 | PrintConsoleString("Retrying to lock B\r\n", 0); 163 | schedule_and_reset(RETRY_DELAY, retryLockB, NULL); 164 | } 165 | return 0; 166 | } 167 | 168 | #define setPresumedLocked(ch) ((ch) ? setPresumedLockedB : setPresumedLockedA) 169 | 170 | uint32_t setPresumedUnlockedA(void *a) { 171 | // if pin says not locked and disconnected, then actually unlocked 172 | if (UC_SENSE_SIGNAL_A_LOCK && (IEC_Prox_Voltage[A] == IEC_DISCONNECTED)) { 173 | lockStatus[A] = unlocked; 174 | statusMismatch[A] = FALSE; 175 | PrintConsoleString("Succesfully unlocked A\r\n", 0); 176 | } 177 | // if pin reads locked then retry unlocking at high rate 178 | else if (!UC_SENSE_SIGNAL_A_LOCK) { 179 | PrintConsoleString("Retrying to unlock A\r\n", 0); 180 | schedule_and_reset(RETRY_DELAY, retryUnlockA, NULL); 181 | } 182 | // pin reads not locked and not disconnected then continue to retry unlocking at low rate 183 | else { 184 | lockStatus[A] = presumedUnlocked; 185 | statusMismatch[A] = FALSE; 186 | PrintConsoleString("A is presumed unlocked \r\n", 0); 187 | schedule_and_reset(UNVERIFIED_UNLOCK_DELAY, retryUnlockA, NULL); 188 | } 189 | return 0; 190 | } 191 | 192 | uint32_t setPresumedUnlockedB(void *a) { 193 | if (UC_SENSE_SIGNAL_B_LOCK && (IEC_Prox_Voltage[B] == IEC_DISCONNECTED)) { 194 | lockStatus[B] = unlocked; 195 | statusMismatch[B] = FALSE; 196 | PrintConsoleString("Succesfully unlocked B\r\n", 0); 197 | } else if (!UC_SENSE_SIGNAL_B_LOCK) { 198 | PrintConsoleString("Retrying to unlock B\r\n", 0); 199 | schedule_and_reset(RETRY_DELAY, retryUnlockB, NULL); 200 | } else { 201 | lockStatus[B] = presumedUnlocked; 202 | statusMismatch[B] = FALSE; 203 | PrintConsoleString("B is presumed unlocked \r\n", 0); 204 | schedule_and_reset(UNVERIFIED_UNLOCK_DELAY, retryUnlockB, NULL); 205 | } 206 | return 0; 207 | } 208 | 209 | #define setPresumedUnlocked(ch) ((ch) ? setPresumedUnlockedB : setPresumedUnlockedA) 210 | 211 | //////////////////////////////////////////////////// 212 | // Retry Functions 213 | //////////////////////////////////////////////////// 214 | 215 | uint32_t retryLockA(void *a) { 216 | if (IEC_Prox_Voltage[A] != IEC_DISCONNECTED) { 217 | startDrivingLock(A); 218 | schedule_and_reset(DRIVE_TIME, endDrivingA, NULL); 219 | schedule_and_reset(DRIVE_TIME, setPresumedLockedA, NULL); 220 | } else { 221 | lockStatus[A] = unlocked; 222 | } 223 | return 0; 224 | } 225 | 226 | uint32_t retryLockB(void *a) { 227 | if (IEC_Prox_Voltage[B] != IEC_DISCONNECTED) { 228 | startDrivingLock(B); 229 | schedule_and_reset(DRIVE_TIME, endDrivingB, NULL); 230 | schedule_and_reset(DRIVE_TIME, setPresumedLockedB, NULL); 231 | } else { 232 | lockStatus[B] = unlocked; 233 | } 234 | return 0; 235 | } 236 | 237 | #define retryLock(ch) ((ch) ? retryLockB : retryLockA) 238 | 239 | uint32_t retryUnlockA(void *a) { 240 | startDrivingUnlock(A); 241 | schedule_and_reset(DRIVE_TIME, endDrivingA, NULL); 242 | schedule_and_reset(DRIVE_TIME, setPresumedUnlockedA, NULL); 243 | return 0; 244 | } 245 | 246 | uint32_t retryUnlockB(void *a) { 247 | startDrivingUnlock(B); 248 | schedule_and_reset(DRIVE_TIME, endDrivingB, NULL); 249 | schedule_and_reset(DRIVE_TIME, setPresumedUnlockedB, NULL); 250 | return 0; 251 | } 252 | 253 | #define retryUnlock(ch) ((ch) ? retryUnlockB : retryUnlockA) 254 | 255 | //////////////////////////////////////////////////// 256 | // Main lock and unlock functions 257 | //////////////////////////////////////////////////// 258 | 259 | #if INLET_LOCK_TYPE == NONE 260 | void lock(uint8_t ch) { 261 | lockStatus[ch] = locked; 262 | } 263 | 264 | void unlock(uint8_t ch) { 265 | lockStatus[ch] = unlocked; 266 | } 267 | #endif 268 | 269 | #if INLET_LOCK_TYPE == FOUR_WIRE 270 | void lock(uint8_t ch) { 271 | PrintConsoleString("Lock ", 0); 272 | if (ch) { 273 | PrintConsoleString("B", 0); 274 | } else { 275 | PrintConsoleString("A", 0); 276 | } 277 | PrintConsoleString("\r\n", 0) 278 | 279 | unschedule(setPresumedUnlocked(ch)); 280 | unschedule(retryUnlock(ch)); 281 | 282 | startDrivingLock(ch); 283 | schedule_if_unscheduled(DRIVE_TIME, endDriving(ch), NULL); 284 | schedule_if_unscheduled(DRIVE_TIME, setPresumedLocked(ch), NULL); 285 | } 286 | 287 | void unlock(uint8_t ch) { 288 | PrintConsoleString("Unlock ", 0); 289 | if (ch) { 290 | PrintConsoleString("B", 0); 291 | } else { 292 | PrintConsoleString("A", 0); 293 | } 294 | PrintConsoleString("\r\n", 0) 295 | 296 | unschedule(setPresumedLocked(ch)); 297 | unschedule(retryLock(ch)); 298 | 299 | startDrivingUnlock(ch); 300 | schedule_if_unscheduled(DRIVE_TIME, endDriving(ch), NULL); 301 | schedule_if_unscheduled(DRIVE_TIME, setPresumedUnlocked(ch), NULL); 302 | } 303 | #endif 304 | 305 | void lock_if_unlocked(uint8_t ch) { 306 | // only lock if state is unlocked or presumedUnlocked 307 | if ((getAndVerifyLockStatus(ch) == unlocked) || (getAndVerifyLockStatus(ch) == presumedUnlocked)) lock(ch); 308 | } 309 | 310 | void unlock_if_locked(uint8_t ch) { 311 | // only unlock if state is locked or presumedLocked 312 | if ((getAndVerifyLockStatus(ch) == locked) || (getAndVerifyLockStatus(ch) == presumedLocked)) unlock(ch); 313 | } 314 | -------------------------------------------------------------------------------- /Project/Sources/lock.h: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | 3 | #ifndef _LOCK_H 4 | #define _LOCK_H 5 | 6 | #define DRIVE_TIME 500 7 | #define RETRY_DELAY 1000 8 | #define UNVERIFIED_UNLOCK_DELAY 5000 9 | 10 | typedef enum { 11 | unknown, 12 | locked, 13 | unlocked, 14 | locking, 15 | unlocking, 16 | presumedLocked, 17 | presumedUnlocked 18 | } lock_status_t; 19 | 20 | #define getSenseSignalValue(ch) ((ch) ? UC_SENSE_SIGNAL_B_LOCK : UC_SENSE_SIGNAL_A_LOCK) 21 | 22 | lock_status_t getLockStatus(uint8_t); 23 | bool getIsLocked(uint8_t ch); 24 | 25 | bool getLockStatusMismatch(uint8_t ch); 26 | 27 | void startDrivingLock(uint8_t); 28 | void startDrivingUnlock(uint8_t); 29 | uint32_t endDrivingA(void *); 30 | uint32_t endDrivingB(void *); 31 | 32 | uint32_t setPresumedLockedA(void *); 33 | uint32_t setPresumedLockedB(void *); 34 | uint32_t setPresumedUnlockedA(void *); 35 | uint32_t setPresumedUnlockedB(void *); 36 | 37 | uint32_t retryLockA(void *); 38 | uint32_t retryLockB(void *); 39 | uint32_t retryUnlockA(void *); 40 | uint32_t retryUnlockB(void *); 41 | 42 | uint32_t verifyLockAStatus(void *); 43 | uint32_t verifyLockBStatus(void *); 44 | 45 | void lock(uint8_t); 46 | void lock_if_unlocked(uint8_t); 47 | void unlock(uint8_t); 48 | void unlock_if_locked(uint8_t); 49 | 50 | #endif -------------------------------------------------------------------------------- /Project/Sources/main.c: -------------------------------------------------------------------------------- 1 | #include /* common defines and macros */ 2 | #include "derivative.h" /* derivative-specific definitions */ 3 | #include "lin.h" 4 | #include "types.h" 5 | #include "hardware.h" 6 | #include "globals.h" 7 | #include "sci.h" 8 | #include "config.h" //set configuration flags here NOTE: different usage from old project 9 | #include "scheduler.h" 10 | #include "pilot.h" 11 | #include "evse_smarts.h" 12 | #include "lin_cfg.h" 13 | #include "lin-cp.h" 14 | #include "lock.h" 15 | #include "j1939.h" 16 | #include "serialCmds.h" 17 | 18 | #define FIVE_MINUTES 5 * 60 * RTI_TICKS_PER_SECOND 19 | //#define FIVE_MINUTES 277800 20 | 21 | bool wakeup_timer = FALSE; 22 | 23 | uint32_t ScheduleTest(void *ptr) { 24 | PrintConsoleString("5 mins\r\n", 0); 25 | return FIVE_MINUTES; 26 | } 27 | 28 | uint32_t end_Init_Timeout(void *ptr) { 29 | enable_desire_to_charge(A, CHARGING_DISABLED_START_DELY); 30 | enable_desire_to_charge(B, CHARGING_DISABLED_START_DELY); 31 | PrintConsoleString("Startup Timeout Expiry\r\n", 0); 32 | return 0; 33 | } 34 | 35 | uint32_t wakeup_timeout(void *ptr) { 36 | wakeup_timer = FALSE; 37 | return 0; 38 | } 39 | 40 | void main(void) { 41 | //uint8_t i,j; 42 | //uint8_t temp; 43 | 44 | bool last_wakeup = FALSE; 45 | bool wakeup = FALSE; 46 | 47 | uint8_t rising_edge_gate = TRUE, falling_edge_gate = TRUE; 48 | 49 | init_hardware(); 50 | 51 | #ifdef LIN_CHARGE_ENABLE 52 | InitializeLINCP(); 53 | #endif 54 | 55 | //configure all timers after LIN init to avoid register overwrite 56 | init_timers(); 57 | 58 | EnableInterrupts; 59 | 60 | //l_sch_set(LI0,LI0_Ver, 0); 61 | 62 | init_delay_table(); 63 | pilot_init(); 64 | schedule_and_reset(FIVE_MINUTES, ScheduleTest, NULL); 65 | schedule_and_reset(PROCESS_FILTERS_DELAY, ProcessFilters, NULL); 66 | 67 | #ifdef EV_CONFIG 68 | disable_desire_to_charge(A, CHARGING_DISABLED_START_DELY); 69 | disable_desire_to_charge(B, CHARGING_DISABLED_START_DELY); 70 | #ifdef J1939_REQD_FOR_CHARGE 71 | disable_desire_to_charge(A, CHARGING_DISABLED_J1939); 72 | disable_desire_to_charge(B, CHARGING_DISABLED_J1939); 73 | #endif 74 | schedule_and_reset(INITIALIZATION_DELAY, end_Init_Timeout, NULL); 75 | #endif 76 | 77 | //PWM_A = 1; 78 | //PWM_B = 1; 79 | 80 | //UC_PILOT_A_STATE_C = 1; 81 | 82 | //DEBUG1 = 1; 83 | //DEBUG2 = 0; 84 | //DEBUG3 = 0; 85 | //DEBUG4 = 0; 86 | 87 | //EnablePWMA(); 88 | //EnablePWMB(); 89 | //SetPilotADutyCycleRaw(5); 90 | //SetPilotBDutyCycle(5); 91 | 92 | //(void)setPresumedUnlockedA(NULL); 93 | //(void)setPresumedUnlockedB(NULL); 94 | //lockStatus[A] = unlocked; 95 | //lockStatus[B] = unlocked; 96 | 97 | evse_init_defaults(A, &(evse_state[A])); 98 | evse_init_defaults(B, &(evse_state[B])); 99 | #ifdef SE_CONFIG 100 | //schedule_and_reset(EVSE_MAIN_LOOP, command_evse, &evse_stateA); //this resets if a command hasn't been received in some amount of time. I don't think we want that 101 | //evse_set_c(&evse_stateA, evse_stateA.default_c); 102 | #ifndef CH_A_ONLY 103 | //schedule_and_reset(EVSE_MAIN_LOOP, command_evse, &evse_stateB); //we can't schedule the same thing twice (without modifying the scheduler). FIXME 104 | //evse_set_c(&evse_stateB, evse_stateB.default_c); 105 | #endif 106 | #endif 107 | 108 | #ifdef EV_CONFIG 109 | unlock(A); 110 | schedule_and_reset(LOCK_CHECK_DELAY, verifyLockAStatus, NULL); 111 | #ifndef CH_A_ONLY 112 | unlock(B); 113 | schedule_and_reset(LOCK_CHECK_DELAY, verifyLockBStatus, NULL); 114 | #endif 115 | schedule_and_reset(SLEEP_CHECK_DELAY, sleepCheck, NULL); 116 | #endif 117 | 118 | PrintConsoleString("Startup\r\n",0); 119 | 120 | for (;;) { 121 | _FEED_COP(); /* feeds the dog */ 122 | 123 | //PTP_PTP4 = !PTP_PTP4; 124 | //SendString(&print_c0buf, "C\r\n", 0); 125 | if (SCI2_receive_flag) { 126 | 127 | //PrintConsoleString(SCI2_receive_buffer, 0); 128 | parse_command(SCI2_receive_buffer); 129 | 130 | SCI2_receive_flag = FALSE; 131 | } 132 | 133 | /* 134 | i = 255; 135 | j = 255; 136 | while(j--) { 137 | while(i--); 138 | //PTM_PTM2 = !PTM_PTM2; 139 | //PTM_PTM3 = !PTM_PTM3; 140 | } 141 | */ 142 | 143 | //execute events with lower priority than interrupts, but higher than scheduler 144 | if (timebase_flag) { 145 | #ifdef EV_CONFIG 146 | #ifdef J1939_XMIT 147 | populate_j1939_messages(); 148 | send_j1939_messages(); 149 | #endif 150 | #endif 151 | timebase_flag = FALSE; 152 | } 153 | 154 | process_delay_table(); //execute scheduled events 155 | 156 | #ifdef CH_A_ONLY 157 | wakeup = evse_present_p(A); 158 | #else 159 | wakeup = (evse_present_p(A) || evse_present_p(B)); 160 | #endif 161 | 162 | if (wakeup && !last_wakeup) { //rising edge 163 | wakeup_timer = TRUE; 164 | schedule_and_reset(VMU_WAKEUP_TIME, wakeup_timeout, NULL); 165 | } 166 | 167 | VMU_WAKEUP = (wakeup && (wakeup_timer || j1939_charge_desired[A] || j1939_charge_desired[B] )); 168 | 169 | last_wakeup = wakeup; 170 | 171 | } /* loop forever */ 172 | /* please make sure that you never leave main */ 173 | } 174 | -------------------------------------------------------------------------------- /Project/Sources/pilot.h: -------------------------------------------------------------------------------- 1 | #ifndef _PILOT_H 2 | #define _PILOT_H 3 | 4 | #include "types.h" 5 | #include "evse_smarts.h" 6 | 7 | typedef enum { GFI_OFF, 8 | GFI_TRANSITIONING, 9 | GFI_ON, 10 | GFI_ERROR, 11 | GFI_FAULT, 12 | GFI_UNKNOWN, 13 | } GFI_STATE; 14 | 15 | typedef enum {OPEN, CLOSED} EVSE_HARDWARE_STATE; 16 | 17 | #define LOCK_MONITOR_TIMEOUT 40 18 | 19 | /******************************************************* 20 | * Arbitrary Filter Code 21 | ********************************************************/ 22 | 23 | enum INHIBIT_STATEB2 { 24 | NOT_INHIBITED, 25 | INHIBITED_TILL_UNPLUG, 26 | INHIBITED_TILL_CLEARED 27 | }; 28 | 29 | #define MAX_FILTER_SIZE 24 30 | #define FILTER_CONSISTENT_TOLERANCE 25 31 | 32 | #define PROCESS_FILTERS_DELAY 10 33 | 34 | #define PILOT_PRESENT(ch) ((PWM_present[ch] || PWM_5duty[ch]) && pilot_in_range[ch]) 35 | 36 | #define EVSE_LEARN_PROX 0 37 | #define EVSE_LOCK_PROX 1 38 | 39 | #define COMM_UNINIT 0 40 | #define COMM_INBAND 1 41 | #define COMM_J1772 2 42 | #define COMM_LIN_SMART_EV 3 43 | 44 | typedef enum { 45 | CHARGING_ENABLED = 0x00, 46 | CHARGING_DISABLED_SLEEPING = 0x01, 47 | CHARGING_DISABLED_ON_REQUEST = 0x02, 48 | CHARGING_DISABLED_ERROR = 0x04, 49 | CHARGING_DISABLED_RCD = 0x08, 50 | CHARGING_DISABLED_UNLOCK_REQ = 0x10, 51 | CHARGING_DISABLED_START_DELY = 0x20, 52 | CHARGING_DISABLED_J1939 = 0x40, 53 | } CHARGE_CONTROL; 54 | 55 | typedef enum {STATE_A=0, STATE_B, STATE_C, STATE_D, STATE_E, STATE_F, STATE_R, STATE_I} PILOT_VOLTAGE ; 56 | 57 | //typedef enum {IEC_DISCONNECTED=0, IEC_13A, IEC_20A, IEC_32A, IEC_63A, IEC_RESERVED_HIGH, IEC_RESERVED_LOW, IEC_J1772_PRESSED, IEC_J1772_RELEASED, IEC_ERROR_LOW, IEC_ERROR_HIGH} IEC_PROX_VOLTAGE; 58 | typedef enum {IEC_ERROR_LOW=0, IEC_RESERVED_LOW, IEC_63A, IEC_J1772_RELEASED, IEC_32A, IEC_40A, IEC_J1772_PRESSED, IEC_20A, IEC_13A, IEC_RESERVED_HIGH, IEC_DISCONNECTED, IEC_ERROR_HIGH} IEC_PROX_VOLTAGE; 59 | 60 | typedef enum {EVGP_INIT=0, EVGP_A, EVGP_B, EVGP_C, EVGP_E, EVGP_F} EV_GEN_PILOT_STATE; 61 | // FIXME: Add high speed communication states 62 | typedef enum {EV_A=0, EV_B1, EV_B2, EV_C2, EV_E, EV_LN, EV_LR, EV_NN, EV_NR, EV_F1} EV_STATE; 63 | typedef enum {EVSE_A0=0, EVSE_B0, EVSE_B1, EVSE_N5, EVSE_B2, EVSE_C2, EVSE_E0, EVSE_F0, EVSE_LT, EVSE_LN, EVSE_LR, EVSE_NT, EVSE_NN, EVSE_NR} EVSE_STATE; 64 | 65 | typedef enum {NO_DUTY=0, DIGITAL_DUTY=1, J1772_DUTY=2, ERROR_DUTY=3} DUTY_STATE; 66 | 67 | typedef enum { 68 | NO_CODE=0, 69 | ERROR_DETECTED, 70 | BSC_ESTABLISHED, 71 | BSC_FAILED, 72 | BSC_TIMEOUT, 73 | DELAY_FINISHED, 74 | HIDE, 75 | PWM_DISABLE_TILL_UNPLUG, 76 | PWM_DISABLE_TILL_CLEARED, 77 | PWM_ENABLE, 78 | } DETERMINE_STATE_CODE; 79 | 80 | 81 | 82 | /******************************************************* 83 | * Initialization 84 | ********************************************************/ 85 | 86 | void pilot_init(void); 87 | void init_communication_structs(void); 88 | 89 | /******************************************************* 90 | * Desire to Charge 91 | ********************************************************/ 92 | 93 | bool desire_to_charge_p(uint8_t); 94 | void disable_desire_to_charge (uint8_t ch, CHARGE_CONTROL cause); 95 | void enable_desire_to_charge (uint8_t ch, CHARGE_CONTROL cause); 96 | 97 | /******************************************************* 98 | * Communication 99 | ********************************************************/ 100 | 101 | #define DELAY_BETWEEN_SOLICITATIONS 5 102 | #define DELAY_BETWEEN_STATUS_MESSAGES 5 103 | 104 | uint32_t SendStatusMessage(void); 105 | void check_for_timeouts(void); 106 | 107 | uint32_t DigitalCommunicationTimeout(void); 108 | uint32_t DigitalSolicitation(void *); 109 | uint32_t DigitalSolicitationFailed(void *); 110 | bool inband_comm_established_p(void); 111 | 112 | /******************************************************* 113 | * State Machine 114 | ********************************************************/ 115 | 116 | #define B0_DELAY 250 117 | 118 | void DetermineEvState(uint8_t, DETERMINE_STATE_CODE); 119 | 120 | void SetEvState(uint8_t, EV_STATE); 121 | 122 | void DetermineEvseState(uint8_t ch, DETERMINE_STATE_CODE); 123 | 124 | void SetEvseState(uint8_t ch, EVSE_STATE); 125 | 126 | uint32_t DelayInCurrentState(void); 127 | 128 | uint8_t InLINState(uint8_t ch); 129 | 130 | /******************************************************* 131 | * Lookup Functions 132 | ********************************************************/ 133 | 134 | uint8_t LookupPilotState(uint8_t); 135 | uint8_t LookupProxState(uint8_t); 136 | uint8_t LookupDutyState(uint8_t); 137 | 138 | /******************************************************* 139 | * Duty Cycle 140 | ********************************************************/ 141 | 142 | uint8_t duty2amps(uint8_t); 143 | uint8_t amps2duty(uint8_t); 144 | 145 | /******************************************************* 146 | * EV Max C 147 | ********************************************************/ 148 | 149 | void update_ev_maxc_pwm(uint8_t); 150 | three_phase_currents_t DetermineEvMaxC(uint8_t, three_phase_currents_t); 151 | 152 | /******************************************************* 153 | * VEHICLE MANAGEMENT SYSTEM (VMS) 154 | ********************************************************/ 155 | 156 | bool evse_present_p (uint8_t); 157 | bool charging_evse_present_p (uint8_t); 158 | bool lin_evse_present_p (uint8_t ch); 159 | bool evse_prox_present_p (uint8_t); 160 | uint32_t process_disable_pwm (void *param); 161 | uint8_t power_unavailable_sleep_p(void); 162 | 163 | /******************************************************* 164 | * Pilot 165 | ********************************************************/ 166 | 167 | bool pilot_check_state_C(uint8_t ch, uint8_t threshold); 168 | bool pilot_check_state_B(uint8_t ch, uint8_t threshold); 169 | 170 | /******************************************************* 171 | * Prox 172 | ********************************************************/ 173 | 174 | void ResetEVSEProxMode(void); 175 | void EVSELearnProx(void); 176 | uint8_t prox_safe_to_energize_filter_func(uint8_t prox_state); 177 | 178 | /******************************************************* 179 | * Input Capture Interrupt 180 | ********************************************************/ 181 | 182 | /******************************************************* 183 | * Arbitrary Filter Code 184 | ********************************************************/ 185 | 186 | #define MAX_FILTER_SIZE 24 187 | #define FILTER_CONSISTENT_TOLERANCE 25 188 | 189 | typedef struct filter { 190 | uint8_t index; 191 | uint8_t size; 192 | uint8_t needs_processing; 193 | uint8_t filter[MAX_FILTER_SIZE]; 194 | } filter_t; 195 | 196 | void filter_init(filter_t*, uint8_t); 197 | void filter_init_value(filter_t* f, uint8_t size, uint8_t value); 198 | void filter_add(filter_t*, uint8_t); 199 | uint8_t filter_check_for_val(filter_t*, uint8_t, uint8_t, uint8_t(*)(uint8_t)); 200 | int8_t filter_check_majority(filter_t*); 201 | uint8_t filter_avg(filter_t*); 202 | void EmptyBuffers(unsigned char *ptr, uint16_t length); 203 | uint32_t ProcessFilters(); 204 | void SetPilotDutyCycle(uint8_t ch, uint8_t duty); 205 | 206 | /******************************************************* 207 | * Specific Filter Code 208 | ********************************************************/ 209 | 210 | void Pilot_Voltage_Filter_Add(uint8_t ch, uint8_t value); 211 | void Pilot_Voltage_Neg_Filter_Add(uint8_t ch, uint8_t value); 212 | void Pilot_Period_Filter_Add(uint8_t ch, uint8_t value); 213 | void Pilot_Duty_Cycle_Filter_Add(uint8_t ch, uint8_t value); 214 | void Prox_Voltage_Filter_Add(uint8_t ch, uint8_t value); 215 | 216 | 217 | /******************************************************* 218 | * Status and current limits of the charging station 219 | ********************************************************/ 220 | 221 | typedef struct { 222 | /* Bit 7: boolean, EVSE ready to supply power 223 | * (False=not ready, True=ready) */ 224 | unsigned int SeSupplyReadyStatus : 1; 225 | /* Bit 6: boolean, EVSE available 226 | * (False=not available, True=available) */ 227 | unsigned int SeAvailabilityStatus : 1; 228 | /* Bit 5: boolean, ventilation active 229 | * (False=not active, True=active) */ 230 | unsigned int SeVentilationStatus : 1; 231 | /* Bit 4: boolean, higher level communication required 232 | * (false=not required, true=required). */ 233 | unsigned int SeHighLevelCommunicationRequest : 1; 234 | /* Bit 3: boolean, charging delayed 235 | * (false=not active, true=active). */ 236 | unsigned int SeDelayStatus : 1; 237 | /* Bit 2: boolean, solicit response 238 | * (true = request EV to respond with a EvMessage1 239 | */ 240 | unsigned int SeSolicitResponse : 1; 241 | /* Bits 1 and 0: void3, reserved, these bits shall be set to 0. */ 242 | unsigned int reserved : 2; 243 | 244 | /* Each MaxCurrent value indicates the maximum current for one phase. 245 | * Resolution is 1A (range: 0A to 80A). Values above 80A are reserved 246 | * and shall not be used. Unavailable phases shall be set to 0. These 247 | * MaxCurrent values implement Table D.2 line 9. 248 | */ 249 | uint8_t SeCurrent1LimitCommand; 250 | uint8_t SeCurrent2LimitCommand; 251 | uint8_t SeCurrent3LimitCommand; 252 | } st_station_t; 253 | 254 | 255 | /******************************************************* 256 | * Status of the EV 257 | ********************************************************/ 258 | 259 | typedef struct { 260 | /* Bit 7: boolean, EV ready to receive power 261 | * (False=not ready, True=ready) */ 262 | unsigned int EvSupplyRequest : 1; 263 | /* Bit 6: boolean, ventilation request 264 | * (false=not requested, true=request) */ 265 | unsigned int EvVentilationRequest : 1; 266 | /* Bit 5: boolean 267 | * (False=not active, True=active) */ 268 | unsigned int EvDelayClearRequest : 1; 269 | /* Bit 4: boolean 270 | * (False=not active, True=active) */ 271 | unsigned int EvDelayAllowRequest : 1; 272 | /* bit 3 to 0: void4, reserved, these bits shall be set to 0. */ 273 | unsigned int reserved : 4; 274 | 275 | /* Each NomCurrent value indicates the nominal current for one phase. 276 | * Resolution is 1A (range: 0A to 80A). Values above 80A are reserved and 277 | * shall not be used. Phases that are not used shall be set to 0. */ 278 | uint8_t EvCurrent1Nominal; 279 | uint8_t EvCurrent2Nominal; 280 | uint8_t EvCurrent3Nominal; 281 | } st_vehicle_t; 282 | 283 | #endif 284 | -------------------------------------------------------------------------------- /Project/Sources/protocol_version_handler.c: -------------------------------------------------------------------------------- 1 | #include "globals.h" 2 | #include "lin-cp.h" 3 | #include "protocol_version_handler.h" 4 | #include "utils.h" 5 | 6 | #ifdef EV_CONFIG 7 | #define XMIT_PVER_EMPTY 0xFF 8 | #define RCV_PVER_EMPTY 0xFF 9 | #define XMIT_PVER(x) Ev##x 10 | #define RCV_PVER(x) Se##x 11 | #define MY_ID_BOOL FALSE 12 | #else 13 | #define XMIT_PVER_EMPTY 0xFF 14 | #define RCV_PVER_EMPTY 0xFF 15 | #define XMIT_PVER(x) Se##x 16 | #define RCV_PVER(x) Ev##x 17 | #define MY_ID_BOOL TRUE 18 | #endif 19 | 20 | #ifdef PWM_CHARGE_ENABLE 21 | #define PWM_SUPPORT PVER_PWM, 22 | #else 23 | #define PWM_SUPPORT 24 | #endif 25 | 26 | uint8_t pversions_list[] = { PWM_SUPPORT PVER_BASE, SUPPORTED_PVERSIONS 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; //the missing commas are intentional, add a full page worth of N/A to not have to worry about it later 27 | 28 | //#ifdef EV_CONFIG 29 | //uint8_t pversions_list[] = { PWM_SUPPORT PVER_BASE, SUPPORTED_PVERSIONS 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; //the missing comma is intentional, add a full page worth of N/A to not have to worry about it later 30 | //#else 31 | //uint8_t pversions_list[] = { PWM_SUPPORT PVER_BASE, PVER_SLASH_1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; //the missing comma is intentional, add a full page worth of N/A to not have to worry about it later 32 | //#endif 33 | 34 | static uint8_t xmit_page[2] = {0,0}; 35 | static uint8_t rcvd_pages[2] = {0,0}; 36 | 37 | uint8_t rcvd_protocol_versions[2][32] = {0}; 38 | 39 | void xmit_protocol_version_page(uint8_t ch) { 40 | #pragma MESSAGE DISABLE C2705 //possible loss of data.is this the flags again? FIXME 41 | LW(ch, l_u8, XMIT_PVER(VersionPageNumber), xmit_page[ch]); 42 | #pragma MESSAGE DISABLE C2705 //possible loss of data.is this the flags again? FIXME 43 | LW(ch, l_u8, XMIT_PVER(SupportedVersion1), pversions_list[xmit_page[ch] * 5]); 44 | #pragma MESSAGE DISABLE C2705 //possible loss of data.is this the flags again? FIXME 45 | LW(ch, l_u8, XMIT_PVER(SupportedVersion2), pversions_list[xmit_page[ch] * 5 + 1]); 46 | #pragma MESSAGE DISABLE C2705 //possible loss of data.is this the flags again? FIXME 47 | LW(ch, l_u8, XMIT_PVER(SupportedVersion3), pversions_list[xmit_page[ch] * 5 + 2]); 48 | #pragma MESSAGE DISABLE C2705 //possible loss of data.is this the flags again? FIXME 49 | LW(ch, l_u8, XMIT_PVER(SupportedVersion4), pversions_list[xmit_page[ch] * 5 + 3]); 50 | #pragma MESSAGE DISABLE C2705 //possible loss of data.is this the flags again? FIXME 51 | LW(ch, l_u8, XMIT_PVER(SupportedVersion5), pversions_list[xmit_page[ch] * 5 + 4]); 52 | 53 | if (pversions_list[(++xmit_page[ch]) * 5 - 1] == XMIT_PVER_EMPTY) xmit_page[ch] = 0; 54 | 55 | //clear flag 56 | LFC(ch, XMIT_PVER(VersionList)); 57 | } 58 | 59 | uint8_t parse_protocol_versions(uint8_t ch) { 60 | #ifdef PWM_CHARGE_ENABLE 61 | uint8_t i = 2; 62 | #else 63 | uint8_t i = 1; 64 | #endif 65 | 66 | uint8_t chosen_pver = 0xFF; 67 | 68 | while (pversions_list[i] != 0xFF) { //check the preference list 69 | if (check_rcvd_pvers(ch, pversions_list[i])) { 70 | chosen_pver = pversions_list[i]; 71 | break; 72 | } 73 | i++; 74 | } 75 | 76 | if ((chosen_pver == 0xFF) && check_rcvd_pvers(ch, PVER_BASE)) { //check the base version if no other version was chosen 77 | chosen_pver = PVER_BASE; 78 | } 79 | 80 | return chosen_pver; 81 | } 82 | 83 | uint8_t rcv_protocol_version_page(uint8_t ch) { 84 | uint8_t rcv_page = LR(ch, l_u8, RCV_PVER(VersionPageNumber)); 85 | uint8_t chosen_pver = 0xFF; 86 | 87 | static uint8_t new_rcvd_protocol_versions[2][32] = {0}; 88 | 89 | #define set_rcvd_pver(pver) new_rcvd_protocol_versions[ch][(pver) >> 3] |= (1 << ((pver) & 0b00000111)) 90 | 91 | rcvd_pages[ch]++; 92 | if (rcv_page == 0) rcvd_pages[ch] = 1; //make sure we can resynchronize 93 | 94 | set_rcvd_pver(LR(ch, l_u8, RCV_PVER(SupportedVersion1))); 95 | set_rcvd_pver(LR(ch, l_u8, RCV_PVER(SupportedVersion2))); 96 | set_rcvd_pver(LR(ch, l_u8, RCV_PVER(SupportedVersion3))); 97 | set_rcvd_pver(LR(ch, l_u8, RCV_PVER(SupportedVersion4))); 98 | set_rcvd_pver(LR(ch, l_u8, RCV_PVER(SupportedVersion5))); 99 | 100 | if ((rcv_page + 1 == rcvd_pages[ch]) && (LR(ch, l_u8, RCV_PVER(SupportedVersion5)) == RCV_PVER_EMPTY)) { 101 | mem_copy(new_rcvd_protocol_versions[ch], rcvd_protocol_versions, 32); 102 | mem_init(new_rcvd_protocol_versions[ch], 32, 0); 103 | #ifdef EV_CONFIG 104 | chosen_pver = parse_protocol_versions(ch); 105 | #else //SE_CONFIG 106 | chosen_pver = 0; //just need to know all pages have been received 107 | #endif 108 | rcvd_pages[ch] = 0; 109 | } 110 | 111 | //clear flag 112 | LFC(ch, RCV_PVER(VersionList)); 113 | return chosen_pver; 114 | } 115 | 116 | bool check_pver_supported(uint8_t pver) { 117 | uint8_t i = 0; 118 | 119 | if (pver == PVER_PWM) return FALSE; //always reject PWM 120 | 121 | while (pversions_list[i] != 0xFF) { 122 | if (pversions_list[i] == pver) return TRUE; 123 | i++; 124 | } 125 | 126 | return FALSE; 127 | } 128 | 129 | #pragma INLINE 130 | bool check_rcvd_pvers(uint8_t ch, uint8_t pver) { 131 | return !!(rcvd_protocol_versions[ch][pver >> 3] & (1 << (pver & 0b00000111))); 132 | } -------------------------------------------------------------------------------- /Project/Sources/protocol_version_handler.h: -------------------------------------------------------------------------------- 1 | #ifndef _protocol_version_HANDLER_H 2 | #define _protocol_version_HANDLER_H 3 | 4 | void xmit_protocol_version_page(uint8_t ch); 5 | uint8_t rcv_protocol_version_page(uint8_t ch); 6 | 7 | bool check_rcvd_pvers(uint8_t ch, uint8_t pver); 8 | bool check_pver_supported(uint8_t pver); 9 | 10 | #endif -------------------------------------------------------------------------------- /Project/Sources/scheduler.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCHEDULER_H 2 | #define _SCHEDULER_H 3 | 4 | #include "types.h" 5 | 6 | #define RTI_MILLISECONDS 1 7 | 8 | //the function pointer 9 | typedef uint32_t (*sfp)(void *); 10 | 11 | // Function that adds a function to the delay list and resets the delay 12 | // if it was already scheduled 13 | void schedule_and_reset(uint32_t, sfp, void *); 14 | // Function that adds a function to the delay list if it wasn't previously 15 | // scheduled 16 | void schedule_if_unscheduled(uint32_t, sfp, void *); 17 | //function that should be called every interrupt to run functions 18 | //void update_delay_table(void); 19 | //call this before using the items_list 20 | void init_delay_table(void); 21 | void unschedule(sfp); 22 | void process_delay_table(void); 23 | void update_delay_count(void); 24 | 25 | uint32_t GetCurrentRTITime(void); 26 | 27 | #endif -------------------------------------------------------------------------------- /Project/Sources/sci.c: -------------------------------------------------------------------------------- 1 | #include "sci.h" 2 | #include "derivative.h" 3 | #include "hardware.h" 4 | //#include "lin.h" 5 | //#include "lin_cfg.h" 6 | //#include "lin_hw_cfg.h" 7 | #include "string_utils.h" 8 | #include "globals.h" 9 | 10 | #define PREV(i, size) (uint8_t)((index - i + size) % size) 11 | #define NEXT(i, size) (uint8_t)((index + i) % size) 12 | 13 | void InitSCIBuffers(void) { 14 | CBufInit(SCI_BUF, &SCI2BDH, print_buf_data, BUFSIZE); 15 | } 16 | 17 | uint8_t get_hex8_from_2char(uint8_t char1, uint8_t char2) { 18 | uint8_t val = 0; 19 | val = (hex_to_dex(char1) << 4) | hex_to_dex(char2); 20 | return val; 21 | } 22 | 23 | uint16_t get_hex16_from_4char(uint8_t *buf, uint8_t index, uint8_t size) { 24 | int i; 25 | uint16_t val = 0; 26 | for (i = 4; i > 0; --i) { 27 | val = (val << 4) | hex_to_dex(buf[PREV(i, size)]); 28 | } 29 | return val; 30 | } 31 | 32 | #define ASCII_LOWERCASE_BIT 0x20 33 | 34 | void SCI_RXRoutine(uint8_t rcv) { 35 | static uint8_t prev; 36 | 37 | SCI2_receive_buffer[SCI2_receive_pointer++] = rcv; 38 | 39 | if (prev == '\r' && rcv == '\n') { 40 | SCI2_receive_buffer[SCI2_receive_pointer] = '\0'; 41 | SCI2_receive_pointer = 0; 42 | SCI2_receive_flag = TRUE; 43 | } 44 | prev = rcv; 45 | } 46 | 47 | void SCIOpenCommunication(circular_buffer *buf, uint32_t baud_rate, bool wakeup, bool rie) { 48 | 49 | uint32_t baud_value; 50 | 51 | // Calculate Baud Module Divisor value depending on bus speed 52 | baud_value = (uint32_t)(MCU_BUS_FREQ / (16 * baud_rate)); 53 | 54 | // Set Baud Rate Modulo Divisor 55 | buf->SCI->BDH = (uint8_t)(baud_value >> 8); 56 | buf->SCI->BDL = (uint8_t)baud_value; 57 | 58 | // Trasmitter and Receiver Enable 59 | buf->SCI->CR2 |= 0x0C; 60 | 61 | SetSCIRIE(buf, rie); 62 | 63 | // If we want to access RXEDGIE/RXEDGIF, we need to set the AMAP bit 64 | //turn AMAP on after setting baud rate and leave it on 65 | buf->SCI->SR2 |= 0x80; 66 | // Check if we want to wakeup on this SCI enable 67 | if(wakeup){ 68 | //NOTE some older versions of the code incorrectly had ASR1 here!! 69 | buf->SCI->SCIACR1 |= 0x80; 70 | } 71 | } 72 | 73 | void SetSCIRIE(circular_buffer *buf, uint8_t mode) { 74 | if (mode == SCI_RIE_OFF) { 75 | // Disable Receive Interrupt 76 | buf->SCI->CR2 &= 0xDF; 77 | // Make two dummy reads to clear the flag 78 | (void)buf->SCI->SR1; 79 | (void)buf->SCI->DRL; 80 | } else if (mode == SCI_RIE_ON) { 81 | // Enable Receive Interrupt 82 | buf->SCI->CR2 |= 0x20; 83 | // Make two dummy reads to clear the flag 84 | (void)buf->SCI->SR1; 85 | (void)buf->SCI->DRL; 86 | } 87 | } 88 | 89 | void SendString(circular_buffer *buf, int8_t *string, uint16_t size) { 90 | uint16_t i; 91 | if (size == 0) { 92 | for (i = 0; string[i] != '\0'; i++) 93 | (void)SCISendBuffer(buf, string[i]); 94 | } else { 95 | for (i = 0; i < size; i++) 96 | (void)SCISendBuffer(buf, string[i]); 97 | } 98 | } 99 | 100 | 101 | void SendFarString(circular_buffer *buf, int8_t * _FAR_ string, uint16_t size){ 102 | uint16_t i; 103 | if (size == 0){ 104 | for (i=0; string[i]!='\0'; i++) 105 | (void)SCISendBuffer(buf, string[i]); 106 | } 107 | else{ 108 | for (i=0; i> 8) ^ ((uint16_t)string[i] & 0x00FF)) & 0xFF; 125 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 126 | (*checksum) = crc; 127 | } 128 | } else { 129 | for (i = 0; i < size; i++) { 130 | (void)SCISendBuffer(buf, string[i]); 131 | index = ((crc >> 8) ^ ((uint16_t)string[i] & 0x00FF)) & 0xFF; 132 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 133 | (*checksum) = crc; 134 | } 135 | } 136 | } 137 | 138 | void SendFarStringC(circular_buffer *buf, 139 | int8_t * _FAR_ string, uint16_t size, uint16_t *checksum) { 140 | uint16_t i; 141 | uint16_t index = 0; 142 | uint16_t crc = *checksum; 143 | 144 | if (size == 0) { 145 | for (i = 0; string[i] != '\0'; i++) { 146 | (void)SCISendBuffer(buf, string[i]); 147 | index = ((crc >> 8) ^ ((uint16_t)string[i] & 0x00FF)) & 0xFF; 148 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 149 | (*checksum) = crc; 150 | } 151 | } else { 152 | for (i = 0; i < size; i++) { 153 | (void)SCISendBuffer(buf, string[i]); 154 | index = ((crc >> 8) ^ ((uint16_t)string[i] & 0x00FF)) & 0xFF; 155 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 156 | (*checksum) = crc; 157 | } 158 | } 159 | } 160 | 161 | void SendCharValueC(circular_buffer *buf, char char_value, uint16_t *checksum) { 162 | uint16_t index = 0; 163 | uint16_t crc = *checksum; 164 | 165 | (void)SCISendBuffer(buf, char_value); 166 | index = ((crc >> 8) ^ ((uint16_t)char_value & 0x00FF)) & 0xFF; 167 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 168 | (*checksum) = crc; 169 | } 170 | #endif 171 | 172 | void SendHexValue(circular_buffer *buf, int raw, uint16_t hex_value) { 173 | uint8_t hex_0, hex_1, hex_2, hex_3; 174 | if (!raw) { 175 | hex_0 = ConvertCharAscii(hex_value & 0x000F); 176 | hex_1 = ConvertCharAscii((hex_value >> 4) & 0x000F); 177 | if (hex_value <= 255) { 178 | (void)SCISendBuffer(buf, hex_1); 179 | (void)SCISendBuffer(buf, hex_0); 180 | } else { 181 | hex_2 = ConvertCharAscii((hex_value >> 8) & 0x000F); 182 | hex_3 = ConvertCharAscii(hex_value >> 12); 183 | (void)SCISendBuffer(buf, hex_3); 184 | (void)SCISendBuffer(buf, hex_2); 185 | (void)SCISendBuffer(buf, hex_1); 186 | (void)SCISendBuffer(buf, hex_0); 187 | } 188 | } else { 189 | hex_0 = hex_value & 0x00FF; 190 | hex_1 = hex_value >> 8; 191 | (void)SCISendBuffer(buf, hex_1); 192 | (void)SCISendBuffer(buf, hex_0); 193 | } 194 | } 195 | 196 | void SendHexValueFixedW(circular_buffer *buf, uint16_t hex_value){ 197 | uint8_t hex_0, hex_1, hex_2, hex_3; 198 | 199 | hex_0 = ConvertCharAscii(hex_value & 0x000F); 200 | hex_1 = ConvertCharAscii((hex_value >> 4) & 0x000F); 201 | hex_2 = ConvertCharAscii((hex_value >> 8) & 0x000F); 202 | hex_3 = ConvertCharAscii(hex_value >> 12); 203 | (void)SCISendBuffer(buf, hex_3); 204 | (void)SCISendBuffer(buf, hex_2); 205 | (void)SCISendBuffer(buf, hex_1); 206 | (void)SCISendBuffer(buf, hex_0); 207 | } 208 | 209 | #ifdef CRC 210 | void SendHexValueC(circular_buffer *buf, uint16_t hex_value, uint16_t *checksum) { 211 | 212 | uint8_t hex_0, hex_1, hex_2, hex_3; 213 | uint16_t index = 0; 214 | uint16_t crc = *checksum; 215 | 216 | hex_0 = ConvertCharAscii(hex_value & 0x000F); 217 | hex_1 = ConvertCharAscii((hex_value >> 4) & 0x000F); 218 | 219 | if (hex_value <= 255) { 220 | // Note hex1 is printed before hex0 221 | index = ((crc >> 8) ^ hex_1) & 0xFF; 222 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 223 | index = ((crc >> 8) ^ hex_0) & 0xFF; 224 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 225 | (*checksum) = crc; 226 | 227 | (void)SCISendBuffer(buf, hex_1); 228 | (void)SCISendBuffer(buf, hex_0); 229 | } else { 230 | hex_3 = ConvertCharAscii(hex_value >> 12); 231 | hex_2 = ConvertCharAscii((hex_value >> 8) & 0x000F); 232 | 233 | index = ((crc >> 8) ^ hex_3) & 0xFF; 234 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 235 | index = ((crc >> 8) ^ hex_2) & 0xFF; 236 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 237 | index = ((crc >> 8) ^ hex_1) & 0xFF; 238 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 239 | index = ((crc >> 8) ^ hex_0) & 0xFF; 240 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 241 | (*checksum) = crc; 242 | 243 | (void)SCISendBuffer(buf, hex_3); 244 | (void)SCISendBuffer(buf, hex_2); 245 | (void)SCISendBuffer(buf, hex_1); 246 | (void)SCISendBuffer(buf, hex_0); 247 | (*checksum) = crc; 248 | } 249 | } 250 | 251 | void SendLongValueC(circular_buffer *buf, uint32_t hex32_value, 252 | uint16_t *checksum) { 253 | int i; 254 | uint8_t hex; 255 | uint16_t index = 0; 256 | uint16_t crc = *checksum; 257 | 258 | // Iterate through all the nibbles of a 32-bit value 259 | for (i = 0; i < 8; ++i) { 260 | uint8_t shift = 4 * (8 - i - 1); 261 | hex = ConvertCharAscii((hex32_value >> shift) & 0x0F); 262 | index = ((crc >> 8) ^ hex) & 0xFF; 263 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 264 | (void)SCISendBuffer(buf, hex); 265 | } 266 | (*checksum) = crc; 267 | } 268 | #endif 269 | 270 | void SendLongValue(circular_buffer *buf, uint32_t hex32_value) { 271 | int i; 272 | uint8_t hex; 273 | 274 | // Iterate through all the nibbles of a 32-bit value 275 | for (i = 0; i < 8; ++i) { 276 | uint8_t shift = 4 * (8 - i - 1); 277 | hex = ConvertCharAscii((hex32_value >> shift) & 0x0F); 278 | (void)SCISendBuffer(buf, hex); 279 | } 280 | } 281 | 282 | void SendDecValue(circular_buffer *buf, uint16_t dec_value) { 283 | uint8_t dec_ones, dec_tens, dec_thous, dec_tenthou; 284 | 285 | dec_ones = dec_value % 10; 286 | dec_tens = (uint8_t)((dec_value / 10) % 10); 287 | dec_thous = (uint8_t)(dec_value / 100) % 10; 288 | dec_tenthou = (uint8_t)(dec_value / 1000); 289 | 290 | if (dec_value > 999) { 291 | (void)SCISendBuffer(buf, ConvertCharAscii(dec_tenthou)); 292 | } 293 | if (dec_value > 99) { 294 | (void)SCISendBuffer(buf, ConvertCharAscii(dec_thous)); 295 | } 296 | if (dec_value > 9) { 297 | (void)SCISendBuffer(buf, ConvertCharAscii(dec_tens)); 298 | } 299 | (void)SCISendBuffer(buf, ConvertCharAscii(dec_ones)); 300 | } 301 | 302 | /* 303 | ifdef CRC 304 | void SendDecValueC(circular_buffer *buf, uint16_t dec_value, uint16_t* checksum){ 305 | 306 | uint8_t dec_ones, dec_tens; 307 | uint16_t index = 0; 308 | uint16_t crc = *checksum; 309 | 310 | if (dec_value > 99) // Take care of numbers bigger than 99 311 | dec_value = 0; 312 | 313 | dec_ones = dec_value % 10; 314 | dec_tens = (UINT8)(dec_value / 10); 315 | 316 | dec_ones = ConvertCharAscii(dec_ones); 317 | index = ((crc >> 8) ^ dec_ones) & 0xFF; 318 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 319 | 320 | dec_tens = ConvertCharAscii(dec_tens); 321 | index = ((crc >> 8) ^ dec_tens) & 0xFF; 322 | crc = (crc_table[index] ^ (crc << 8)) & 0xFFFF; 323 | 324 | (void)SCISendBuffer(buf, dec_tens); 325 | (void)SCISendBuffer(buf, dec_ones); 326 | 327 | (*checksum) = crc; 328 | } 329 | #endif 330 | */ 331 | 332 | uint8_t ConvertCharAscii(uint8_t value) { 333 | if (value < 10) 334 | return value + 48; 335 | else 336 | return value + 55; 337 | } 338 | 339 | void CBufInit(circular_buffer *buf, void *sci_base, uint8_t *data, uint16_t size) { 340 | buf->inpos = buf->outpos = 0; 341 | buf->SCI = sci_base; 342 | buf->data = data; 343 | buf->size = size; 344 | } 345 | 346 | bool CBufPush(circular_buffer *buf, char in) { 347 | uint16_t x = buf->inpos; 348 | 349 | //if (++x >= bufsize) x = 0; 350 | if (++x >= buf->size) x = 0; 351 | 352 | if (x == buf->outpos) { 353 | //PrintConsoleString("\r\nBUFFER FULL!!!", 0); YOU CANT PRINT FROM HERE! IT CREATES A CIRCULAR FUNC CALL UNTIL YOU RUN OUT OF OR OVERRUN MEM 354 | return FALSE; // buffer full 355 | } 356 | 357 | buf->data[buf->inpos] = in; 358 | buf->inpos = x; 359 | 360 | return TRUE; 361 | } 362 | 363 | bool CBufPop(circular_buffer *buf) { 364 | uint16_t x = buf->outpos; 365 | if (x == buf->inpos) return FALSE; // buffer empty 366 | //if (++x >= bufsize) x = 0; 367 | if (++x >= buf->size) x = 0; 368 | buf->outpos = x; 369 | return TRUE; 370 | } 371 | 372 | bool CBufEmpty(circular_buffer *buf) { 373 | if (buf->outpos == buf->inpos) { 374 | return TRUE; 375 | } else { 376 | return FALSE; 377 | } 378 | } 379 | 380 | /* void SCISendBuffer(circular_buffer *buf, uint8_t c){ // send a byte out */ 381 | /* (void)CBufPush(buf, c); */ 382 | /* buf->SCI->CR2 |= 0x80; */ 383 | /* } */ 384 | 385 | void SCISendBuffer(circular_buffer *buf, uint8_t c) { // send a byte out 386 | bool ret_value; 387 | uint8_t i; 388 | 389 | i = 0; 390 | do { 391 | ret_value = CBufPush(buf, c); 392 | buf->SCI->CR2 |= 0x80; 393 | 394 | if (ret_value) 395 | return; 396 | 397 | if (!check_interrupts_disabled()) 398 | DelayMs(5); 399 | else 400 | return; 401 | 402 | } while (i++ < 2); 403 | } 404 | 405 | #undef NEXT 406 | #undef PREV 407 | #undef CBUFSIZE 408 | -------------------------------------------------------------------------------- /Project/Sources/sci.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCI_H 2 | #define _SCI_H 3 | 4 | #include "types.h" 5 | #include "config.h" 6 | #include "derivative.h" 7 | 8 | #define SCI_RIE_OFF 0 9 | #define SCI_RIE_ON 1 10 | 11 | // SCI module numbers 12 | 13 | #define SCI_BUF &print_buf 14 | 15 | #define BUFSIZE 240 16 | 17 | typedef struct { 18 | 19 | uint8_t BDH; 20 | uint8_t BDL; 21 | uint8_t CR1; 22 | uint8_t CR2; 23 | uint8_t SR1; 24 | uint8_t SR2; 25 | uint8_t DRH; 26 | uint8_t DRL; 27 | 28 | } SCI_REG; 29 | 30 | #define SCIASR1 BDH 31 | #define SCIACR1 BDL 32 | #define SCIACR2 CR1 33 | 34 | typedef struct { 35 | SCI_REG *SCI; 36 | uint16_t inpos; 37 | uint16_t outpos; 38 | uint8_t *data; 39 | uint16_t size; 40 | } circular_buffer; 41 | 42 | void SCI_RXRoutine(uint8_t rcv); 43 | 44 | uint8_t get_hex8_from_2char(uint8_t char1, uint8_t char2); 45 | uint16_t get_hex16_from_4char(uint8_t *buf, uint8_t index, uint8_t size); 46 | 47 | void InitSCIBuffers(void); 48 | void CBufInit(circular_buffer *buf, void *sci_base, uint8_t *data, uint16_t size); 49 | bool CBufPush(circular_buffer *buf, char in); 50 | bool CBufPop(circular_buffer *buf); 51 | bool CBufEmpty(circular_buffer *buf); 52 | ; 53 | 54 | void SCIOpenCommunication(circular_buffer *buf, uint32_t baud_rate, bool wakeup, bool rie); 55 | void SetSCIRIE(circular_buffer *buf, uint8_t mode); 56 | void SCISendBuffer(circular_buffer *buf, uint8_t c); 57 | void SendString(circular_buffer *buf, int8_t *string, uint16_t size); 58 | void SendFarString(circular_buffer *buf, int8_t * _FAR_ string, uint16_t size); 59 | void SendStringC(circular_buffer *buf, int8_t *string, uint16_t size, uint16_t *checksum); 60 | void SendFarStringC(circular_buffer *buf, 61 | int8_t * _FAR_ string, uint16_t size, uint16_t *checksum); 62 | void SendHexValue(circular_buffer *buf, int raw, uint16_t hex_value); 63 | void SendHexValueC(circular_buffer *buf, uint16_t hex_value, uint16_t *checksum); 64 | void SendLongValueC(circular_buffer *buf, uint32_t hex32_value, 65 | uint16_t *checksum); 66 | void SendDecValue(circular_buffer *buf, uint16_t dec_value); 67 | //void SendDecValueC(circular_buffer *buf, uint16_t dec_value, uint16_t* checksum); 68 | void SendCharValueC(circular_buffer *buf, char char_value, uint16_t *checksum); 69 | uint8_t ConvertCharAscii(uint8_t value); 70 | void SendLongValue(circular_buffer *buf, uint32_t hex32_value); 71 | void SendHexValueFixedW(circular_buffer *buf, uint16_t hex_value); 72 | 73 | #define PrintS2(x, size) SendString(&print_buf, x, size); 74 | #define PrintDec2(x) SendDecValue(&print_buf, x); 75 | #define PrintChar2(x) SCISendBuffer(&print_buf, x); 76 | #define PrintHex2(x) SendHexValue(&print_buf, 0, x); 77 | #define PrintLongHex2(x) SendLongValue(&print_buf, x); 78 | #define PrintFixedHex2(x) SendHexValueFixedW(&print_buf, x) 79 | 80 | #define PrintConsoleString(x, y) PrintS2(x, y) 81 | #define PrintConsoleDec(x) PrintDec2(x) 82 | #define PrintConsoleChar(x) PrintChar2(x) 83 | #define PrintConsoleHex(x) PrintHex2(x) 84 | #define PrintConsoleLongHex(x) PrintLongHex2(x) 85 | #define PrintConsoleHexFixedW(x) PrintFixedHex2(x) 86 | #define PrintConsoleFarString(x,y) SendFarString(&print_buf, x, y); 87 | 88 | #define EnPrintConsoleString(e, x, y) if(e) {PrintConsoleString(x, y)} 89 | #define EnPrintConsoleDec(e, x) if(e) {PrintConsoleDec(x)} 90 | #define EnPrintConsoleChar(e, x) if(e) {PrintConsoleChar(x)} 91 | #define EnPrintConsoleHex(e, x) if(e) {PrintConsoleHex(x)} 92 | #define EnPrintConsoleLongHex(e, x) if(e) {PrintConsoleLongHex(x)} 93 | #define EnPrintConsoleHexFixedW(e, x) if(e) {PrintConsoleHexFixedW(x)} 94 | 95 | #define PrintCmdsString(x, y) PrintS2(x, y) 96 | #define PrintCmdsHex(x) PrintHex2(x) 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /Project/Sources/serialCmds.c: -------------------------------------------------------------------------------- 1 | #include /* common defines and macros */ 2 | #include "derivative.h" /* derivative-specific definitions */ 3 | #include "types.h" 4 | #include "hardware.h" 5 | #include "globals.h" 6 | #include "sci.h" 7 | #include "config.h" //set configuration flags here NOTE: different usage from old project 8 | #include "pilot.h" 9 | #include "evse_smarts.h" 10 | #include "info_code_handler.h" 11 | 12 | #define well_formed_end(pos) (buffer[pos] == '#' || (buffer[pos] == '\r' && buffer[pos + 1] == '\n')) 13 | 14 | void command_contactor(uint8_t ch, uint8_t state) { 15 | #ifdef CH_A_ONLY 16 | int8_t xmit_buffer[] = ">C:X\r\n"; 17 | #else 18 | int8_t xmit_buffer[] = ">C:X:Y\r\n"; 19 | #endif 20 | 21 | xmit_buffer[3] = state ? 'C' : 'O'; 22 | #ifndef CH_A_ONLY 23 | xmit_buffer[5] = ch ? 'B' : 'A'; 24 | #endif 25 | 26 | PrintCmdsString(xmit_buffer, 0); 27 | } 28 | 29 | uint8_t char_to_hex(uint8_t input) { 30 | if (input >= '0' && input <= '9') { 31 | return input - '0'; 32 | } else if (input >= 'A' && input <= 'F') { 33 | return input - 'A' + 10; 34 | } else { 35 | return 255; 36 | } 37 | } 38 | 39 | int16_t parse_Hex(uint8_t sixteens, uint8_t ones) { 40 | sixteens = char_to_hex(sixteens); 41 | ones = char_to_hex(ones); 42 | if (sixteens == 255 || ones == 255) { 43 | return -1; 44 | } 45 | return sixteens * 16 + ones; 46 | } 47 | 48 | void parse_command(int8_t *buffer) { 49 | uint8_t tempC1, tempC2, tempC3; 50 | int16_t tempS1; 51 | #ifdef SE_CONFIG 52 | int16_t tempS2, tempS3, tempS4; 53 | three_phase_currents_t tempCts; 54 | #endif 55 | 56 | if (buffer[0] == '>') { 57 | switch (buffer[1]) { 58 | case 'E': 59 | switch (buffer[2]) { 60 | case ':': 61 | tempS1 = parse_Hex(buffer[3], buffer[4]); 62 | if (tempS1 < 0) { 63 | PrintCmdsString(">E:02#Malformed Command 1\r\n", 0); 64 | } else { 65 | if (well_formed_end(5)) { 66 | PrintConsoleString("Error:", 0); 67 | PrintConsoleHex((uint8_t)tempS1); 68 | PrintConsoleString("\r\n", 0); 69 | } else { 70 | PrintCmdsString(">E:02#Malformed Command 2\r\n", 0); 71 | } 72 | } 73 | break; 74 | case 'U': 75 | switch (buffer[3]) { 76 | case ':': 77 | tempS1 = parse_Hex(buffer[4], buffer[5]); 78 | if (tempS1 < 0) { 79 | PrintCmdsString(">E:02#Malformed Command 3\r\n", 0); 80 | } else { 81 | switch (tempS1) { 82 | case 0x81: 83 | tempC1 = CHARGING_DISABLED_SLEEPING; 84 | break; 85 | case 0x82: 86 | tempC1 = CHARGING_DISABLED_ON_REQUEST; 87 | break; 88 | case 0x83: 89 | tempC1 = CHARGING_DISABLED_ERROR; 90 | break; 91 | case 0x84: 92 | tempC1 = CHARGING_DISABLED_RCD; 93 | break; 94 | case 0x85: 95 | tempC1 = CHARGING_DISABLED_UNLOCK_REQ; 96 | break; 97 | default: 98 | PrintCmdsString(">E:02#Malformed Command 4\r\n", 0); 99 | goto BREAKOUT; //break out of the rest of the parsing 100 | } 101 | switch (buffer[6]) { 102 | case ':': 103 | switch (buffer[7]) { 104 | case 'S': 105 | tempC2 = 1; 106 | break; 107 | case 'C': 108 | tempC2 = 0; 109 | break; 110 | default: 111 | PrintCmdsString(">E:02#Malformed Command 5\r\n", 0); 112 | goto BREAKOUT; //break out of the rest of the parsing 113 | } 114 | break; 115 | default: 116 | PrintCmdsString(">E:02#Malformed Command 6\r\n", 0); 117 | goto BREAKOUT; //break out of the rest of the parsing 118 | } 119 | if (well_formed_end(8)) { 120 | if (tempC2) { 121 | disable_desire_to_charge(A, tempC1); 122 | } else { 123 | enable_desire_to_charge(A, tempC1); 124 | } 125 | } else if (buffer[8] == ':') { //channel specified 126 | switch (buffer[9]) { 127 | case 'A': 128 | tempC3 = 0; 129 | break; 130 | case 'B': 131 | tempC3 = 1; 132 | break; 133 | default: 134 | PrintCmdsString(">E:02#Malformed Command 7\r\n", 0); 135 | goto BREAKOUT; //break out of the rest of the parsing 136 | } 137 | if (well_formed_end(10)) { 138 | if (tempC2) { 139 | disable_desire_to_charge(tempC3, tempC1); 140 | } else { 141 | enable_desire_to_charge(tempC3, tempC1); 142 | } 143 | } else { 144 | PrintCmdsString(">E:02#Malformed Command 8\r\n", 0); 145 | } 146 | } else { 147 | PrintCmdsString(">E:02#Malformed Command 9\r\n", 0); 148 | } 149 | } 150 | break; 151 | default: 152 | PrintCmdsString(">E:02#Malformed Command 10\r\n", 0); 153 | } 154 | break; 155 | default: 156 | PrintCmdsString(">E:02#Malformed Command 11\r\n", 0); 157 | } 158 | break; 159 | #ifdef SE_CONFIG 160 | case 'S': 161 | switch (buffer[2]) { 162 | case 'I': 163 | switch (buffer[3]) { 164 | case ':': 165 | tempS1 = parse_Hex(buffer[4], buffer[5]); 166 | tempC1 = 0; 167 | if (tempS1 < 0) { 168 | PrintCmdsString(">E:02#Malformed Command 12\r\n", 0); 169 | } else { 170 | tempS2 = tempS3 = tempS4 = tempS1; 171 | if (well_formed_end(6)) { 172 | //nothing more necessary 173 | } else if (buffer[6] == ':') { 174 | if ((buffer[7] == 'A' || buffer[7] == 'B') && well_formed_end(8)) { 175 | tempC1 = buffer[7] - 'A'; //0 for A and 1 for B 176 | } else if (buffer[9] == ':' && buffer[12] == ':') { 177 | if (buffer[15] == ':' && (buffer[16] == 'A' || buffer[16] == 'B') && well_formed_end(17)) { 178 | tempC1 = buffer[16] - 'A'; //0 for A and 1 for B 179 | } else if (!well_formed_end(15)) { 180 | PrintCmdsString(">E:02#Malformed Command 14\r\n", 0); 181 | goto BREAKOUT; //break out of the rest of the parsing 182 | } 183 | tempS2 = parse_Hex(buffer[7], buffer[8]); 184 | tempS3 = parse_Hex(buffer[10], buffer[11]); 185 | tempS4 = parse_Hex(buffer[13], buffer[14]); 186 | if (tempS2 < 0 || tempS3 < 0 || tempS4 < 0) { 187 | PrintCmdsString(">E:02#Malformed Command 15\r\n", 0); 188 | goto BREAKOUT; //break out of the rest of the parsing 189 | } 190 | } else { 191 | PrintCmdsString(">E:02#Malformed Command 16\r\n", 0); 192 | goto BREAKOUT; //break out of the rest of the parsing 193 | } 194 | } else { 195 | PrintCmdsString(">E:02#Malformed Command 17\r\n", 0); 196 | goto BREAKOUT; //break out of the rest of the parsing 197 | } 198 | tempCts.C1_L1 = (uint8_t)tempS1; 199 | tempCts.C2_L2 = (uint8_t)tempS2; 200 | tempCts.C3_L3 = (uint8_t)tempS3; 201 | tempCts.C4_N = (uint8_t)tempS4; 202 | 203 | tempCts.pwm = tempCts.C1_L1; 204 | if (tempCts.C2_L2 < tempCts.pwm) tempCts.pwm = tempCts.C2_L2; 205 | if (tempCts.C3_L3 < tempCts.pwm) tempCts.pwm = tempCts.C3_L3; 206 | if (tempCts.C4_N < tempCts.pwm) tempCts.pwm = tempCts.C4_N; 207 | 208 | //printf("$$ch:%c::%x,%x,%x,%x,%x::%d,%d,%d,%d,%d\n", tempC1? 'B': 'A', tempCts.pwm, tempCts.C1_L1, tempCts.C2_L2, tempCts.C3_L3, tempCts.C4_N, tempCts.pwm, tempCts.C1_L1, tempCts.C2_L2, tempCts.C3_L3, tempCts.C4_N); 209 | evse_set_c(&(evse_state[tempC1]), tempCts); 210 | } 211 | break; 212 | default: 213 | PrintCmdsString(">E:02#Malformed Command 18\r\n", 0); 214 | } 215 | break; 216 | default: 217 | PrintCmdsString(">E:02#Malformed Command 19\r\n", 0); 218 | } 219 | break; 220 | #endif 221 | case 'I': 222 | switch(buffer[2]) { 223 | case 'C': 224 | switch(buffer[3]) { 225 | case ':': 226 | tempS1 = parse_Hex(buffer[4],buffer[5]); 227 | if (tempS1 < 0) { 228 | PrintCmdsString(">E:02#Malformed Command 20\r\n",0); 229 | } else { 230 | if (buffer[6] == ':') { 231 | if (well_formed_end(8)) { 232 | tempC1 = A; 233 | } else if (buffer[8] == ':') { 234 | if ((buffer[9] == 'A' || buffer[9] == 'B') && well_formed_end(10)) { 235 | tempC1 = buffer[9] - 'A'; //0 for A and 1 for B 236 | } else { 237 | PrintCmdsString(">E:02#Malformed Command 21\r\n",0); 238 | goto BREAKOUT; //break out of the rest of the parsing 239 | } 240 | } else { 241 | PrintCmdsString(">E:02#Malformed Command 22\r\n",0); 242 | goto BREAKOUT; //break out of the rest of the parsing 243 | } 244 | } else { 245 | PrintCmdsString(">E:02#Malformed Command 23\r\n",0); 246 | goto BREAKOUT; //break out of the rest of the parsing 247 | } 248 | } 249 | switch(buffer[7]) { 250 | case 'S': 251 | set_info_code(tempC1, (uint8_t) tempS1); 252 | break; 253 | case 'P': 254 | set_priority_info_code(tempC1, (uint8_t) tempS1); 255 | break; 256 | case 'C': 257 | clear_info_code(tempC1, (uint8_t) tempS1); 258 | break; 259 | default: 260 | PrintCmdsString(">E:02#Malformed Command 24\r\n",0); 261 | } 262 | break; 263 | default: 264 | PrintCmdsString(">E:02#Malformed Command 25\r\n",0); 265 | } 266 | break; 267 | default: 268 | PrintCmdsString(">E:02#Malformed Command 26\r\n",0); 269 | } 270 | break; 271 | default: 272 | PrintCmdsString(">E:01#Invalid Command\r\n", 0); 273 | } 274 | } //else (if the received string does not start with '>') do nothing 275 | 276 | BREAKOUT:; //; required because no statements follow 277 | } 278 | -------------------------------------------------------------------------------- /Project/Sources/serialCmds.h: -------------------------------------------------------------------------------- 1 | #ifndef _SERIALCMDS_H 2 | #define _SERIALCMDS_H 3 | 4 | #include "types.h" 5 | 6 | #define CONT_OPEN 0 7 | #define CONT_CLOSED 1 8 | 9 | void command_contactor(uint8_t ch, uint8_t state); 10 | void parse_command(int8_t *buffer); 11 | 12 | #endif -------------------------------------------------------------------------------- /Project/Sources/string_utils.c: -------------------------------------------------------------------------------- 1 | /************************************************************************************************* 2 | * File: string_utils.c 3 | * Originator: Andrew Robbins 4 | * Date Created: December 7, 2018 5 | * Description: Since using the standard string library would consume a lot of space and only 6 | * a few functions may be used, this file can be used to add only the neccessary 7 | * functions needed and also customize certain ones to the needs of the VEL SW 8 | *************************************************************************************************/ 9 | 10 | #include "sci.h" 11 | #include "string_utils.h" 12 | 13 | /*int isalpha(char ch) { 14 | ch |= 0x20; // Convert to lowercase 15 | return ((ch >= 'a') && (ch <= 'z')); 16 | }*/ 17 | 18 | uint8_t StringEqualsSafe(const char *string1, const char *string2, uint8_t length) { 19 | uint8_t i = 0; 20 | 21 | if (string1 == ((void *)0) || string1[0] == 0 || string2 == ((void *)0) || string2[0] == 0) { 22 | return 0; 23 | } 24 | 25 | for (i = 0; (string1[i] != 0 && string2[i] != 0 && i < length); i++) { 26 | if (string1[i] != string2[i]) { 27 | return 0; 28 | } 29 | } 30 | 31 | if (i == length && string1[i] == 0 && string2[i] == 0) { 32 | return 1; 33 | } else { 34 | return 0; 35 | } 36 | } 37 | 38 | uint8_t hex_to_dex(uint8_t ch) { 39 | uint8_t val = 0; 40 | 41 | if (ch >= 'a' && ch <= 'f') { 42 | val = 10 + ch - 'a'; 43 | } else if (ch >= 'A' && ch <= 'F') { 44 | val = 10 + ch - 'A'; 45 | } else if (ch >= '0' && ch <= '9') { 46 | val = ch - '0'; 47 | } 48 | return val; 49 | } 50 | 51 | uint8_t HexToDex(uint8_t ch) { 52 | uint8_t val = 0; 53 | 54 | if (ch >= 'a' && ch <= 'f') { 55 | val = (uint8_t)((uint8_t)10 + (uint8_t)ch - (uint8_t)'a'); 56 | } else if (ch >= 'A' && ch <= 'F') { 57 | val = (uint8_t)((uint8_t)10 + (uint8_t)ch - (uint8_t)'A'); 58 | } else if (ch >= '0' && ch <= '9') { 59 | val = (uint8_t)((uint8_t)ch - (uint8_t)'0'); 60 | } else { 61 | //Error invalid Hex number 62 | val = (uint8_t)UINT8_MAX; 63 | } 64 | 65 | return val; 66 | } 67 | 68 | uint8_t HexStringToInt(const char *hexString, uint8_t numHexDigits, uint32_t *const result) { 69 | uint32_t intResult = 0; 70 | uint8_t digitResult = 0; 71 | uint8_t i = 0; 72 | 73 | if (hexString == ((void *)0) || hexString[0] == 0 || result == ((void *)0)) { 74 | return 0; 75 | } 76 | 77 | for (i = 0; hexString[i] != 0 && i < numHexDigits; i++) { 78 | digitResult = HexToDex((uint8_t)hexString[i]); 79 | 80 | if (digitResult == UINT8_MAX) { 81 | return 0; 82 | } 83 | 84 | intResult = (intResult << 4) | digitResult; 85 | } 86 | 87 | if (i != numHexDigits) { 88 | return 0; 89 | } 90 | 91 | *result = intResult; 92 | 93 | return 1; 94 | } 95 | 96 | int32_t _atoi(char *src) { 97 | int i; 98 | int32_t value = 0; 99 | 100 | for (i = 0; src[i] != '\0'; ++i) { 101 | char ch = src[i]; 102 | if ((ch >= '0') && (ch <= '9')) { 103 | value = (10 * value) + (ch - '0'); 104 | } else { 105 | return 0; 106 | } 107 | } 108 | return value; 109 | } 110 | 111 | #define INT_DIGITS 10 /* enough for 32 bit integer */ 112 | 113 | char *itoa(int32_t intToConvert) { 114 | // Room for INT_DIGITS digits, - and '\0' 115 | static char buf[INT_DIGITS + 2]; 116 | char *p = buf + INT_DIGITS + 1; //points to terminating '\0' 117 | 118 | if (intToConvert >= 0) { 119 | do { 120 | *--p = '0' + (intToConvert % 10); 121 | intToConvert /= 10; 122 | } while (intToConvert != 0); 123 | return p; 124 | } else { //intToConvert negative 125 | do { 126 | *--p = '0' - (intToConvert % 10); 127 | intToConvert /= 10; 128 | } while (intToConvert != 0); 129 | *--p = '-'; 130 | } 131 | return p; 132 | } 133 | 134 | //The function that performs the conversion. Accepts a buffer with "enough space" 135 | //and populates it with a string of hexadecimal digits.Returns the length in digits 136 | char *uintToHexStr(uint32_t num) { 137 | // Room for INT_DIGITS digits, - and '\0' 138 | static char buff[INT_DIGITS + 1]; 139 | static char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', 140 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 141 | int len = 0, k = 0; 142 | 143 | do { //for every 4 bits 144 | //get the equivalent hex digit 145 | buff[len] = hex[num & 0xF]; 146 | len++; 147 | num >>= 4; 148 | } while (num != 0); 149 | 150 | //since we get the digits in the wrong order reverse the digits in the buffer 151 | for (; k < len / 2; k++) { //xor swapping 152 | buff[k] ^= buff[len - k - 1]; 153 | buff[len - k - 1] ^= buff[k]; 154 | buff[k] ^= buff[len - k - 1]; 155 | } 156 | 157 | //null terminate the buffer and return the length in digits 158 | buff[len] = '\0'; 159 | return buff; 160 | } 161 | 162 | /*void ChecksumOfString(const char *stringToChecksum, uint16_t stringSize, uint16_t *checksum) { 163 | uint16_t i; 164 | 165 | for (i = 0; i < stringSize; i++) { 166 | AccumulateCRC(stringToChecksum[i], checksum); 167 | } 168 | }*/ 169 | 170 | /*uint8_t StringAppend(const char *string1, const char *string2, char *resultString, uint16_t resultStringSize) { 171 | int i; 172 | int resultIndex = 0; 173 | uint8_t success = 0; 174 | 175 | for (i = 0; string1[i] != 0 && resultIndex < resultStringSize; i++) { 176 | resultString[resultIndex] = string1[i]; 177 | ++resultIndex; 178 | } 179 | 180 | for (i = 0; string2[i] != 0 && resultIndex < resultStringSize; i++) { 181 | resultString[resultIndex] = string2[i]; 182 | ++resultIndex; 183 | success = 1; 184 | } 185 | 186 | return success; 187 | }*/ 188 | 189 | //Simple version of snprintf with two arguments passed, one string one int 190 | //This could be upgraded to full implementation with a byte **array for "infinite" args 191 | uint16_t SafeNPrintf(char *buffer, uint16_t maxSize, const char *format, char *strArg, int32_t intArg) { 192 | uint16_t i = 0; 193 | uint16_t j = 0; 194 | uint16_t charsPrinted = 0; 195 | char *intStr; 196 | 197 | for (i = 0; format[i] != 0; i++) { 198 | if (charsPrinted < maxSize) { 199 | if (format[i] != '%') { 200 | buffer[charsPrinted] = format[i]; 201 | ++charsPrinted; 202 | } else { 203 | ++i; 204 | switch (format[i]) { 205 | case 'c': 206 | if (strArg[0] != 0) { 207 | buffer[charsPrinted] = strArg[0]; 208 | ++charsPrinted; 209 | } 210 | break; 211 | case 's': 212 | for (j = 0; (strArg[j] != 0 && charsPrinted < maxSize); j++) { 213 | buffer[charsPrinted] = strArg[j]; 214 | ++charsPrinted; 215 | } 216 | break; 217 | case 'd': 218 | //8 bit signed 219 | //break; 220 | case 'u': 221 | //8 bit unsigned 222 | //break; 223 | case 'l': 224 | //16 bit signed 225 | intStr = itoa(intArg); 226 | 227 | for (j = 0; (intStr[j] != 0 && charsPrinted < maxSize); j++) { 228 | buffer[charsPrinted] = intStr[j]; 229 | ++charsPrinted; 230 | } 231 | break; 232 | case 'x': 233 | break; 234 | case 'X': 235 | break; 236 | default: 237 | break; 238 | } 239 | } 240 | } else { 241 | break; 242 | } 243 | } 244 | 245 | if (charsPrinted == maxSize) { 246 | --charsPrinted; 247 | } 248 | 249 | buffer[charsPrinted] = 0; 250 | 251 | return charsPrinted; 252 | } 253 | -------------------------------------------------------------------------------- /Project/Sources/string_utils.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************************* 2 | * File: string_utils.h 3 | * Originator: Andrew Robbins 4 | * Date Created: December 7, 2018 5 | * Description: Since using the standard string library would consume a lot of space and only 6 | * a few functions may be used, this file can be used to add only the neccessary 7 | * functions needed and also customize certain ones to the needs of the VEL SW 8 | *************************************************************************************************/ 9 | 10 | #ifndef _STRING_UTILS_H 11 | #define _STRING_UTILS_H 12 | 13 | #include "types.h" 14 | 15 | #define UINT8_MAX 255 16 | #define UINT16_MAX 65535 17 | #define INT32_MAX 2147483647 18 | 19 | uint8_t StringEqualsSafe(const char *, const char *, uint8_t); 20 | uint8_t hex_to_dex(uint8_t); 21 | uint8_t HexToDex(uint8_t); 22 | uint8_t HexStringToInt(const char *, uint8_t, uint32_t *const); 23 | int32_t _atoi(char *); 24 | char *itoa(int32_t); 25 | char *uintToHexStr(uint32_t); 26 | void AccumulateCRC(char, uint16_t *); 27 | //uint8_t StringAppend(const char *, const char *, char *, uint16_t); 28 | uint16_t SafeNPrintf(char *, uint16_t, const char *, char *, int32_t); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /Project/Sources/timers.h: -------------------------------------------------------------------------------- 1 | #ifndef _TIMERS_H 2 | #define _TIMERS_H 3 | 4 | //Analog sample timeout timer 5 | #define TIMER_1_PERIOD 31200 //24 MHz * 1.3 ms = 31200 6 | #define timer_1_reset() TC1 = (TCNT + TIMER_1_PERIOD) & 0xFFFF 7 | 8 | //LIN timer 9 | #define TIMER_6_PERIOD 60000 //24 MHz * 2.5 ms = 60000 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /Project/Sources/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H_ 2 | #define __TYPES_H_ 3 | 4 | #ifndef STANDALONE 5 | 6 | typedef unsigned char uint8_t; 7 | typedef unsigned short uint16_t; 8 | typedef unsigned long int uint32_t; 9 | typedef signed char int8_t; 10 | typedef short int16_t; 11 | typedef long int int32_t; 12 | typedef unsigned char bool; /*unsigned 8 bit bool definition */ 13 | 14 | #define NULL ((void *)0) 15 | 16 | /******************************************************* 17 | * Booleans 18 | ********************************************************/ 19 | #define ON 1 20 | #define OFF 0 21 | 22 | #define TRUE 1 23 | #define FALSE 0 24 | 25 | #define OUTPUT 1 26 | #define INPUT 0 27 | 28 | #endif 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /Project/Sources/utils.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "utils.h" 3 | 4 | /* read_int16_le: 5 | * Reads a 16 bit integer from the given circular buffer of length size 6 | * at the specified offset. 7 | * 8 | * Note: The offset is updated by 2 to reflect the size 9 | * of the read integer in bytes 10 | * Returns: The just read 16-bit short integer 11 | */ 12 | 13 | int16_t read_int16_le(uint8_t *buf, int *offset, int size) { 14 | int16_t value; 15 | int i = *offset; 16 | 17 | value = (buf[(i + 1) % size] & 0x00FF); 18 | value = (value << 8) | (buf[i] & 0x00FF); 19 | 20 | *offset = (i + 2) % size; 21 | return value; 22 | } 23 | 24 | /* write_int16_le: 25 | * Write a signed or unsigned short value at the given offset in buf 26 | * The bytes are written in a LITTLE ENDIAN fashion 27 | */ 28 | 29 | void write_int16_le(int16_t value, uint8_t *buf, int *offset, int size) { 30 | int i = *offset; 31 | 32 | buf[i % size] = value & 0xFF; 33 | buf[(i + 1) % size] = ((value >> 8) & 0xFF); 34 | *offset = (i + 2) % size; 35 | } 36 | 37 | /* read_int16_be: 38 | * Reads a 16 bit integer from the given circular buffer of length size 39 | * at the specified offset. 40 | * 41 | * Note: The offset is updated by 2 to reflect the size 42 | * of the read integer in bytes 43 | * Returns: The just read 16-bit short integer 44 | */ 45 | int16_t read_int16_be(int8_t *buf, int *offset, int size) 46 | { 47 | int16_t value; 48 | int i = *offset; 49 | 50 | value = (buf[i % size] & 0x00FF); 51 | value = (value << 8) | (buf[(i + 1) % size] & 0x00FF); 52 | *offset = (i + 2) % size; 53 | return value; 54 | } 55 | 56 | /* write_int16_be: 57 | * Write a signed or unsigned short value at the given offset in buf 58 | * The bytes are written in a BIG ENDIAN fashion 59 | */ 60 | 61 | void write_int16_be(int16_t value, int8_t *buf, int *offset, int size) 62 | { 63 | int i = *offset; 64 | 65 | buf[i % size] = ((value >> 8) & 0xFF); 66 | buf[(i + 1) % size] = value & 0xFF; 67 | *offset = (i + 2) % size; 68 | } 69 | 70 | /* read_int32_be: 71 | * Reads a 32 bit integer from the given circular buffer of length size 72 | * at the specified offset. 73 | * Assumes BIG ENDIAN encoding 74 | * 75 | * Note: The offset is updated by 4 to reflect the size 76 | * of the read integer in bytes 77 | * Returns: The just read integer 78 | */ 79 | #pragma MESSAGE DISABLE C12056 80 | int32_t read_int32_be(uint8_t *buf, int *offset, int size) 81 | { 82 | int32_t value; 83 | int i = *offset; 84 | 85 | value = (buf[i % size] & 0x000000FF); 86 | value = (value << 8) | (buf[(i + 1) % size] & 0x000000FF); 87 | value = (value << 8) | (buf[(i + 2) % size] & 0x000000FF); 88 | value = (value << 8) | (buf[(i + 3) % size] & 0x000000FF); 89 | 90 | *offset = (i + 4) % size; 91 | 92 | return value; 93 | } 94 | 95 | /* write_int32_be: 96 | * Write a signed or unsigned short value at the given offset in buf 97 | * The bytes are written in a BIG ENDIAN fashion 98 | */ 99 | 100 | void write_int32_be(uint32_t value, uint8_t *buf, int *offset, int size) 101 | { 102 | int i = *offset; 103 | 104 | buf[i % size] = ((value >> 24) & 0xFF); 105 | buf[(i + 1) % size] = ((value >> 16) & 0xFF); 106 | buf[(i + 2) % size] = ((value >> 8) & 0xFF); 107 | buf[(i + 3) % size] = value & 0xFF; 108 | 109 | *offset = (i + 4) % size; 110 | } 111 | 112 | bool mem_compare(void * _FAR_ obj1_p, void * _FAR_ obj2_p, uint8_t size) { 113 | uint8_t i, * _FAR_ obj1_u8_p = obj1_p, * _FAR_ obj2_u8_p = obj2_p; 114 | 115 | for (i = 0; i < size; i++) { 116 | if (obj1_u8_p[i] != obj2_u8_p[i]) { 117 | return FALSE; 118 | } 119 | } 120 | 121 | return TRUE; 122 | } 123 | 124 | void mem_init(void * _FAR_ obj_p, uint8_t size, uint8_t value) { 125 | uint8_t i, * _FAR_ obj_u8_p = obj_p; 126 | 127 | for (i = 0; i < size; i++) { 128 | obj_u8_p[i] = value; 129 | } 130 | } 131 | 132 | void mem_copy(void * _FAR_ source_p, void * _FAR_ dest_p, uint8_t size) { 133 | uint8_t i, * _FAR_ source_u8_p = source_p, * _FAR_ dest_u8_p = dest_p; 134 | 135 | for (i = 0; i < size; i++) { 136 | dest_u8_p[i] = source_u8_p[i]; 137 | } 138 | } -------------------------------------------------------------------------------- /Project/Sources/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef _UTILS_H 2 | #define _UTILS_H 3 | 4 | #include "derivative.h" 5 | 6 | int16_t read_int16_le(uint8_t *buf, int *offset, int size); 7 | void write_int16_le(int16_t value, uint8_t *buf, int *offset, int size); 8 | int16_t read_int16_be(uint8_t *buf, int *offset, int size); 9 | void write_int16_be(int16_t value, uint8_t *buf, int *offset, int size); 10 | int32_t read_int32_be(uint8_t *buf, int *offset, int size); 11 | void write_int32_be(uint32_t value, uint8_t *buf, int *offset, int size); 12 | 13 | bool mem_compare(void * _FAR_ obj1_p, void * _FAR_ obj2_p, uint8_t size); 14 | void mem_init(void * _FAR_ obj_p, uint8_t size, uint8_t value); 15 | void mem_copy(void * _FAR_ source_p, void * _FAR_ dest_p, uint8_t size); 16 | 17 | #endif -------------------------------------------------------------------------------- /Project/USBDM.ini: -------------------------------------------------------------------------------- 1 | 2 | 3 | [HI-WAVE] 4 | Target=usbdm 5 | CPU=Hc12 6 | MainFrame=0,1,-1,-1,-1,-1,212,95,2314,1482 7 | TOOLBAR=57600 57601 32795 0 57635 57634 57637 0 57671 57669 0 32777 32776 32782 32780 32781 32778 0 32806 8 | 9 | 10 | 11 | [USBDM] 12 | COMSETTINGS=SETCOMM DRIVER NOPROTOCOL NOPERIODICAL 13 | 14 | [USBDM HCS12_GDI_SETTINGS] 15 | CMDFILE0=CMDFILE STARTUP ON "startup.cmd" 16 | CMDFILE1=CMDFILE RESET ON "reset.cmd" 17 | CMDFILE2=CMDFILE PRELOAD ON "preload.cmd" 18 | CMDFILE3=CMDFILE POSTLOAD ON "postload.cmd" 19 | MCUID=0x2DC 20 | CMDFILE4=CMDFILE VPPON ON "vppon.cmd" 21 | CMDFILE5=CMDFILE VPPOFF ON "vppoff.cmd" 22 | CMDFILE6=CMDFILE UNSECURE ON "unsecure.cmd" 23 | CHIPSECURE=CHIPSECURE SETUP 0xFF0F 0x3 0x2 24 | DBG_S12X_0=DBG GENERAL DISARM_ON PROTECT_OFF ANALYZE_ON STEPATRUN_ON 25 | DBG_S12X_1=DBG PREDEFINED SELECT 0 26 | S12XDBG_TRIGGER_A=RangeAllowed:1 AccessSizeCompareAllowed:0 Disabled:0 BreakAllways:0 Range:0 OutsideRange:0 CompareMismatch:0 DataToCompare:0 DataToCompareMask:0 AccessSizeCompare: 0 WordAccessSizeCompare:0 Core:0 27 | S12XDBG_TRIGGER_B=RangeAllowed:0 AccessSizeCompareAllowed:1 Disabled:0 BreakAllways:0 Range:0 OutsideRange:0 CompareMismatch:0 DataToCompare:0 DataToCompareMask:0 AccessSizeCompare: 0 WordAccessSizeCompare:0 Core:0 28 | S12XDBG_TRIGGER_C=RangeAllowed:1 AccessSizeCompareAllowed:0 Disabled:0 BreakAllways:0 Range:0 OutsideRange:0 CompareMismatch:0 DataToCompare:0 DataToCompareMask:0 AccessSizeCompare: 0 WordAccessSizeCompare:0 Core:0 29 | S12XDBG_TRIGGER_D=RangeAllowed:0 AccessSizeCompareAllowed:1 Disabled:0 BreakAllways:0 Range:0 OutsideRange:0 CompareMismatch:0 DataToCompare:0 DataToCompareMask:0 AccessSizeCompare: 0 WordAccessSizeCompare:0 Core:0 30 | DBG_S12X_2=DBG PREDEFINED DBGENGINE TRACE HCS12X RECORDBEFORE PUREPC 31 | DBG_S12X_3=DBG PREDEFINED DBGENGINE SEQUENCER 0x02 0x02 0x02 32 | NV_PARAMETER_FILE= 33 | NV_SAVE_WSP=0 34 | NV_AUTO_ID=1 35 | -------------------------------------------------------------------------------- /Project/lin_cfg/lin_cfg.c: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | 3 | #ifdef EV_CONFIG 4 | 5 | #include "lin_cfg_ev.c" 6 | 7 | #else //SE_CONFIG 8 | 9 | #include "lin_cfg_evse.c" 10 | 11 | #endif -------------------------------------------------------------------------------- /Project/lin_cfg/lin_cfg.h: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | 3 | #ifdef EV_CONFIG 4 | 5 | #include "lin_cfg_ev.h" 6 | 7 | #else //SE_CONFIG 8 | 9 | #include "lin_cfg_evse.h" 10 | 11 | #endif -------------------------------------------------------------------------------- /Project/lin_cfg/lin_hw_cfg.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Freescale Semiconductor Inc. 4 | * (c) Copyright 2013-2016 Freescale Semiconductor, Inc. 5 | * Copyright 2016-2020 NXP 6 | * ALL RIGHTS RESERVED. 7 | * 8 | ****************************************************************************//*! 9 | * 10 | * @file lin_hw_cfg.h 11 | * 12 | * @author FPT Software 13 | * 14 | * @version 1.0 15 | * 16 | * @date Thu Nov 05 10:13:02 EST 2020 17 | * 18 | * @brief Hardware configuration file 19 | * 20 | ******************************************************************************/ 21 | #ifndef _LIN_HW_CFG_H 22 | #define _LIN_HW_CFG_H 23 | #include "derivative.h" 24 | #include "config.h" 25 | 26 | typedef enum { 27 | SCI0, 28 | SCI1, 29 | SCI2, 30 | SCI3, 31 | SCI4, 32 | SCI5, 33 | GPIO, 34 | SLIC 35 | } lin_hardware_name; 36 | 37 | 38 | /* MCU type definition */ 39 | #define _S08_ 0 40 | #define _S12_ 1 41 | #define _S12X_ 2 42 | #define _K_ 3 43 | 44 | #define SCI_V2 0 45 | #define SCI_V4 1 46 | #define SCI_V5 2 47 | #define SCI_V6 3 48 | 49 | /* SCI version */ 50 | #define SCI_VERSION SCI_V5 51 | 52 | /* Type of MCU */ 53 | #ifdef S12X 54 | #define _MCU_ _S12X_ 55 | #else 56 | #define _MCU_ _S12_ 57 | #endif 58 | 59 | /* Resynchronization support */ 60 | #define __RESYN_EN 0 61 | 62 | /* Autobaud support */ 63 | #define AUTOBAUD 0 64 | 65 | /* Interface type that MCU uses */ 66 | #define XGATE_SUPPORT 0 67 | #define _LIN_XGATE_ 0 68 | #define _LIN_SCI_ 1 69 | #define _LIN_UART_ 0 70 | #define _LIN_SLIC_ 0 71 | #define _LIN_GPIO_ 0 72 | /*********** SCI HARDWARE SECTION *********/ 73 | #ifdef S12X 74 | #define NUM_OF_SCI_CHANNEL 6 75 | #else 76 | #define NUM_OF_SCI_CHANNEL 3 77 | #endif 78 | 79 | /* SCI Base Register definition */ 80 | #ifdef S12X 81 | #define SCI0_ADDR 0x00C8 82 | #define SCI1_ADDR 0x00D0 83 | #define SCI2_ADDR 0x00B8 84 | #define SCI3_ADDR 0x00C0 85 | #define SCI4_ADDR 0x0130 86 | #define SCI5_ADDR 0x0138 87 | #else 88 | #define SCI0_ADDR 0x00C8 89 | #define SCI1_ADDR 0x00D0 90 | #define SCI2_ADDR 0x00E8 91 | #endif 92 | 93 | /* Use SCI Channel */ 94 | #define _SCI0_ 1 95 | #define _SCI1_ 1 96 | #define _SCI2_ 0 97 | #define _SCI3_ 0 98 | #define _SCI4_ 0 99 | #define _SCI5_ 0 100 | 101 | /* MCU bus frequency */ 102 | #define MCU_BUS_FREQ 24000000 103 | 104 | /* Default interrupt period of the timer for LIN is TIME_BASE_PERIOD micro seconds */ 105 | #define TIME_BASE_PERIOD 500 106 | 107 | /* max idle timeout for all networks = idle_timeout_value*1000000/time_base_period */ 108 | #define _MAX_IDLE_TIMEOUT_ 10000 /* idle_timeout_value = 5s */ 109 | #endif -------------------------------------------------------------------------------- /Project/prm/Project.prm: -------------------------------------------------------------------------------- 1 | /* This is a linker parameter file for the MC9S12G96 */ 2 | NAMES END /* CodeWarrior will pass all the needed files to the linker by command line. But here you may add your own files too. */ 3 | 4 | SEGMENTS /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */ 5 | 6 | /* Register space */ 7 | /* IO_SEG = PAGED 0x0000 TO 0x03FF; intentionally not defined */ 8 | 9 | /* RAM */ 10 | RAM = READ_WRITE 0x2000 TO 0x3FFF; 11 | 12 | /* D-Flash */ 13 | DFLASH = READ_ONLY 0x000400 TO 0x000FFF; 14 | 15 | /* non-paged FLASHs */ 16 | ROM_1000 = READ_ONLY 0x1000 TO 0x1FFF; 17 | ROM_4000 = READ_ONLY 0x4000 TO 0x7FFF; 18 | ROM_C000 = READ_ONLY 0xC000 TO 0xFEFF; 19 | /* VECTORS = READ_ONLY 0xFF00 TO 0xFFFF; intentionally not defined: used for VECTOR commands below */ 20 | //OSVECTORS = READ_ONLY 0xFF80 TO 0xFFFF; /* OSEK interrupt vectors (use your vector.o) */ 21 | 22 | /* paged FLASH: 0x8000 TO 0xBFFF; addressed through PPAGE */ 23 | PAGE_0A = READ_ONLY 0x0A8000 TO 0x0ABFFF; 24 | PAGE_0B = READ_ONLY 0x0B8000 TO 0x0BBFFF; 25 | PAGE_0C = READ_ONLY 0x0C8000 TO 0x0C8FFF; 26 | PAGE_0C_A000 = READ_ONLY 0x0CA000 TO 0x0CBFFF; 27 | PAGE_0E = READ_ONLY 0x0E8000 TO 0x0EBFFF; 28 | /* PAGE_0D = READ_ONLY 0x0D8000 TO 0x0DBFFF; not used: equivalent to ROM_4000 */ 29 | /* PAGE_0F = READ_ONLY 0x0F8000 TO 0x0FBEFF; not used: equivalent to ROM_C000 */ 30 | END 31 | 32 | PLACEMENT /* here all predefined and user segments are placed into the SEGMENTS defined above. */ 33 | _PRESTART, /* Used in HIWARE format: jump to _Startup at the code start */ 34 | STARTUP, /* startup data structures */ 35 | ROM_VAR, /* constant variables */ 36 | STRINGS, /* string literals */ 37 | VIRTUAL_TABLE_SEGMENT, /* C++ virtual table segment */ 38 | //.ostext, /* OSEK */ 39 | NON_BANKED, /* runtime routines which must not be banked */ 40 | COPY /* copy down information: how to initialize variables */ 41 | /* in case you want to use ROM_4000 here as well, make sure 42 | that all files (incl. library files) are compiled with the 43 | option: -OnB=b */ 44 | INTO ROM_C000/*, ROM_1000, ROM_4000*/; 45 | 46 | DEFAULT_ROM INTO PAGE_0A, PAGE_0B, PAGE_0C, PAGE_0C_A000, PAGE_0E ; 47 | 48 | //.stackstart, /* eventually used for OSEK kernel awareness: Main-Stack Start */ 49 | SSTACK, /* allocate stack first to avoid overwriting variables on overflow */ 50 | //.stackend, /* eventually used for OSEK kernel awareness: Main-Stack End */ 51 | DEFAULT_RAM INTO RAM; 52 | 53 | //.vectors INTO OSVECTORS; /* OSEK */ 54 | END 55 | 56 | ENTRIES /* keep the following unreferenced variables */ 57 | /* OSEK: always allocate the vector table and all dependent objects */ 58 | //_vectab OsBuildNumber _OsOrtiStackStart _OsOrtiStart 59 | END 60 | 61 | STACKSIZE 0x800 62 | 63 | VECTOR 0 _Startup /* reset vector: this is the default entry point for a C/C++ application. */ 64 | VECTOR 1 _Startup 65 | VECTOR 2 _Startup 66 | //VECTOR 0 Entry /* reset vector: this is the default entry point for an Assembly application. */ 67 | //INIT Entry /* for assembly applications: that this is as well the initialization entry point */ 68 | -------------------------------------------------------------------------------- /Project/prm/S12X.bbl: -------------------------------------------------------------------------------- 1 | /* global s-record file */ 2 | OPENFILE "%ABS_FILE%.glo" 3 | format = motorola 4 | busWidth = 1 5 | SRECORD=Sx 6 | 7 | /* "EABI compliant encoded global" address to global */ 8 | len = 0x1800000 9 | origin = 0x1000000 10 | destination = 0 11 | SENDBYTE 1 "%ABS_FILE%" 12 | 13 | /* physical flash window to global */ 14 | len = 0x4000 15 | destination = 0x7F8000 16 | origin = 0x008000 17 | SENDBYTE 1 "%ABS_FILE%" 18 | 19 | /* logical non banked flash at $4000 and $C000 to global */ 20 | len = 0x4000 21 | destination = 0x7F4000 22 | origin = 0x004000 23 | SENDBYTE 1 "%ABS_FILE%" 24 | destination = 0x7FC000 25 | origin = 0x00C000 26 | SENDBYTE 1 "%ABS_FILE%" 27 | 28 | /* logical 1 MB banked flash to global */ 29 | destination = 0x700000 30 | origin = 0xc08000 31 | SENDBYTE 1 "%ABS_FILE%" 32 | destination = 0x704000 33 | origin = 0xc18000 34 | SENDBYTE 1 "%ABS_FILE%" 35 | destination = 0x708000 36 | origin = 0xc28000 37 | SENDBYTE 1 "%ABS_FILE%" 38 | destination = 0x70c000 39 | origin = 0xc38000 40 | SENDBYTE 1 "%ABS_FILE%" 41 | destination = 0x710000 42 | origin = 0xc48000 43 | SENDBYTE 1 "%ABS_FILE%" 44 | destination = 0x714000 45 | origin = 0xc58000 46 | SENDBYTE 1 "%ABS_FILE%" 47 | destination = 0x718000 48 | origin = 0xc68000 49 | SENDBYTE 1 "%ABS_FILE%" 50 | destination = 0x71c000 51 | origin = 0xc78000 52 | SENDBYTE 1 "%ABS_FILE%" 53 | destination = 0x720000 54 | origin = 0xc88000 55 | SENDBYTE 1 "%ABS_FILE%" 56 | destination = 0x724000 57 | origin = 0xc98000 58 | SENDBYTE 1 "%ABS_FILE%" 59 | destination = 0x728000 60 | origin = 0xca8000 61 | SENDBYTE 1 "%ABS_FILE%" 62 | destination = 0x72c000 63 | origin = 0xcb8000 64 | SENDBYTE 1 "%ABS_FILE%" 65 | destination = 0x730000 66 | origin = 0xcc8000 67 | SENDBYTE 1 "%ABS_FILE%" 68 | destination = 0x734000 69 | origin = 0xcd8000 70 | SENDBYTE 1 "%ABS_FILE%" 71 | destination = 0x738000 72 | origin = 0xce8000 73 | SENDBYTE 1 "%ABS_FILE%" 74 | destination = 0x73c000 75 | origin = 0xcf8000 76 | SENDBYTE 1 "%ABS_FILE%" 77 | destination = 0x740000 78 | origin = 0xd08000 79 | SENDBYTE 1 "%ABS_FILE%" 80 | destination = 0x744000 81 | origin = 0xd18000 82 | SENDBYTE 1 "%ABS_FILE%" 83 | destination = 0x748000 84 | origin = 0xd28000 85 | SENDBYTE 1 "%ABS_FILE%" 86 | destination = 0x74c000 87 | origin = 0xd38000 88 | SENDBYTE 1 "%ABS_FILE%" 89 | destination = 0x750000 90 | origin = 0xd48000 91 | SENDBYTE 1 "%ABS_FILE%" 92 | destination = 0x754000 93 | origin = 0xd58000 94 | SENDBYTE 1 "%ABS_FILE%" 95 | destination = 0x758000 96 | origin = 0xd68000 97 | SENDBYTE 1 "%ABS_FILE%" 98 | destination = 0x75c000 99 | origin = 0xd78000 100 | SENDBYTE 1 "%ABS_FILE%" 101 | destination = 0x760000 102 | origin = 0xd88000 103 | SENDBYTE 1 "%ABS_FILE%" 104 | destination = 0x764000 105 | origin = 0xd98000 106 | SENDBYTE 1 "%ABS_FILE%" 107 | destination = 0x768000 108 | origin = 0xda8000 109 | SENDBYTE 1 "%ABS_FILE%" 110 | destination = 0x76c000 111 | origin = 0xdb8000 112 | SENDBYTE 1 "%ABS_FILE%" 113 | destination = 0x770000 114 | origin = 0xdc8000 115 | SENDBYTE 1 "%ABS_FILE%" 116 | destination = 0x774000 117 | origin = 0xdd8000 118 | SENDBYTE 1 "%ABS_FILE%" 119 | destination = 0x778000 120 | origin = 0xde8000 121 | SENDBYTE 1 "%ABS_FILE%" 122 | destination = 0x77c000 123 | origin = 0xdf8000 124 | SENDBYTE 1 "%ABS_FILE%" 125 | destination = 0x780000 126 | origin = 0xe08000 127 | SENDBYTE 1 "%ABS_FILE%" 128 | destination = 0x784000 129 | origin = 0xe18000 130 | SENDBYTE 1 "%ABS_FILE%" 131 | destination = 0x788000 132 | origin = 0xe28000 133 | SENDBYTE 1 "%ABS_FILE%" 134 | destination = 0x78c000 135 | origin = 0xe38000 136 | SENDBYTE 1 "%ABS_FILE%" 137 | destination = 0x790000 138 | origin = 0xe48000 139 | SENDBYTE 1 "%ABS_FILE%" 140 | destination = 0x794000 141 | origin = 0xe58000 142 | SENDBYTE 1 "%ABS_FILE%" 143 | destination = 0x798000 144 | origin = 0xe68000 145 | SENDBYTE 1 "%ABS_FILE%" 146 | destination = 0x79c000 147 | origin = 0xe78000 148 | SENDBYTE 1 "%ABS_FILE%" 149 | destination = 0x7a0000 150 | origin = 0xe88000 151 | SENDBYTE 1 "%ABS_FILE%" 152 | destination = 0x7a4000 153 | origin = 0xe98000 154 | SENDBYTE 1 "%ABS_FILE%" 155 | destination = 0x7a8000 156 | origin = 0xea8000 157 | SENDBYTE 1 "%ABS_FILE%" 158 | destination = 0x7ac000 159 | origin = 0xeb8000 160 | SENDBYTE 1 "%ABS_FILE%" 161 | destination = 0x7b0000 162 | origin = 0xec8000 163 | SENDBYTE 1 "%ABS_FILE%" 164 | destination = 0x7b4000 165 | origin = 0xed8000 166 | SENDBYTE 1 "%ABS_FILE%" 167 | destination = 0x7b8000 168 | origin = 0xee8000 169 | SENDBYTE 1 "%ABS_FILE%" 170 | destination = 0x7bc000 171 | origin = 0xef8000 172 | SENDBYTE 1 "%ABS_FILE%" 173 | destination = 0x7c0000 174 | origin = 0xf08000 175 | SENDBYTE 1 "%ABS_FILE%" 176 | destination = 0x7c4000 177 | origin = 0xf18000 178 | SENDBYTE 1 "%ABS_FILE%" 179 | destination = 0x7c8000 180 | origin = 0xf28000 181 | SENDBYTE 1 "%ABS_FILE%" 182 | destination = 0x7cc000 183 | origin = 0xf38000 184 | SENDBYTE 1 "%ABS_FILE%" 185 | destination = 0x7d0000 186 | origin = 0xf48000 187 | SENDBYTE 1 "%ABS_FILE%" 188 | destination = 0x7d4000 189 | origin = 0xf58000 190 | SENDBYTE 1 "%ABS_FILE%" 191 | destination = 0x7d8000 192 | origin = 0xf68000 193 | SENDBYTE 1 "%ABS_FILE%" 194 | destination = 0x7dc000 195 | origin = 0xf78000 196 | SENDBYTE 1 "%ABS_FILE%" 197 | destination = 0x7e0000 198 | origin = 0xf88000 199 | SENDBYTE 1 "%ABS_FILE%" 200 | destination = 0x7e4000 201 | origin = 0xf98000 202 | SENDBYTE 1 "%ABS_FILE%" 203 | destination = 0x7e8000 204 | origin = 0xfa8000 205 | SENDBYTE 1 "%ABS_FILE%" 206 | destination = 0x7ec000 207 | origin = 0xfb8000 208 | SENDBYTE 1 "%ABS_FILE%" 209 | destination = 0x7f0000 210 | origin = 0xfc8000 211 | SENDBYTE 1 "%ABS_FILE%" 212 | destination = 0x7f4000 213 | origin = 0xfd8000 214 | SENDBYTE 1 "%ABS_FILE%" 215 | destination = 0x7f8000 216 | origin = 0xfe8000 217 | SENDBYTE 1 "%ABS_FILE%" 218 | destination = 0x7fc000 219 | origin = 0xff8000 220 | SENDBYTE 1 "%ABS_FILE%" 221 | 222 | CLOSE 223 | 224 | /*****************************************************************************/ 225 | 226 | /* logical s-record file */ 227 | 228 | OPENFILE "%ABS_FILE%.s19" 229 | format = motorola 230 | busWidth = 1 231 | SRECORD=Sx 232 | 233 | /* logical non banked flash at $4000 and $C000 to logical */ 234 | len = 0x4000 235 | origin = 0x004000 236 | destination = 0x004000 237 | SENDBYTE 1 "%ABS_FILE%" 238 | 239 | len = 0x4000 240 | origin = 0x00C000 241 | destination = 0xC000 242 | SENDBYTE 1 "%ABS_FILE%" 243 | 244 | /* physical flash window to logical */ 245 | len = 0x4000 246 | origin = 0x008000 247 | destination = 0xFE8000 248 | SENDBYTE 1 "%ABS_FILE%" 249 | 250 | 251 | /* logical 1 MB banked flash to logical */ 252 | len = 0x400000 253 | origin = 0xC00000 254 | destination = 0xC00000 255 | SENDBYTE 1 "%ABS_FILE%" 256 | 257 | 258 | /* global 1 MB banked flash to logical */ 259 | len = 0x4000 260 | origin = 0x1700000 261 | destination = 0xc08000 262 | SENDBYTE 1 "%ABS_FILE%" 263 | origin = 0x1704000 264 | destination = 0xc18000 265 | SENDBYTE 1 "%ABS_FILE%" 266 | origin = 0x1708000 267 | destination = 0xc28000 268 | SENDBYTE 1 "%ABS_FILE%" 269 | origin = 0x170c000 270 | destination = 0xc38000 271 | SENDBYTE 1 "%ABS_FILE%" 272 | origin = 0x1710000 273 | destination = 0xc48000 274 | SENDBYTE 1 "%ABS_FILE%" 275 | origin = 0x1714000 276 | destination = 0xc58000 277 | SENDBYTE 1 "%ABS_FILE%" 278 | origin = 0x1718000 279 | destination = 0xc68000 280 | SENDBYTE 1 "%ABS_FILE%" 281 | origin = 0x171c000 282 | destination = 0xc78000 283 | SENDBYTE 1 "%ABS_FILE%" 284 | origin = 0x1720000 285 | destination = 0xc88000 286 | SENDBYTE 1 "%ABS_FILE%" 287 | origin = 0x1724000 288 | destination = 0xc98000 289 | SENDBYTE 1 "%ABS_FILE%" 290 | origin = 0x1728000 291 | destination = 0xca8000 292 | SENDBYTE 1 "%ABS_FILE%" 293 | origin = 0x172c000 294 | destination = 0xcb8000 295 | SENDBYTE 1 "%ABS_FILE%" 296 | origin = 0x1730000 297 | destination = 0xcc8000 298 | SENDBYTE 1 "%ABS_FILE%" 299 | origin = 0x1734000 300 | destination = 0xcd8000 301 | SENDBYTE 1 "%ABS_FILE%" 302 | origin = 0x1738000 303 | destination = 0xce8000 304 | SENDBYTE 1 "%ABS_FILE%" 305 | origin = 0x173c000 306 | destination = 0xcf8000 307 | SENDBYTE 1 "%ABS_FILE%" 308 | origin = 0x1740000 309 | destination = 0xd08000 310 | SENDBYTE 1 "%ABS_FILE%" 311 | origin = 0x1744000 312 | destination = 0xd18000 313 | SENDBYTE 1 "%ABS_FILE%" 314 | origin = 0x1748000 315 | destination = 0xd28000 316 | SENDBYTE 1 "%ABS_FILE%" 317 | origin = 0x174c000 318 | destination = 0xd38000 319 | SENDBYTE 1 "%ABS_FILE%" 320 | origin = 0x1750000 321 | destination = 0xd48000 322 | SENDBYTE 1 "%ABS_FILE%" 323 | origin = 0x1754000 324 | destination = 0xd58000 325 | SENDBYTE 1 "%ABS_FILE%" 326 | origin = 0x1758000 327 | destination = 0xd68000 328 | SENDBYTE 1 "%ABS_FILE%" 329 | origin = 0x175c000 330 | destination = 0xd78000 331 | SENDBYTE 1 "%ABS_FILE%" 332 | origin = 0x1760000 333 | destination = 0xd88000 334 | SENDBYTE 1 "%ABS_FILE%" 335 | origin = 0x1764000 336 | destination = 0xd98000 337 | SENDBYTE 1 "%ABS_FILE%" 338 | origin = 0x1768000 339 | destination = 0xda8000 340 | SENDBYTE 1 "%ABS_FILE%" 341 | origin = 0x176c000 342 | destination = 0xdb8000 343 | SENDBYTE 1 "%ABS_FILE%" 344 | origin = 0x1770000 345 | destination = 0xdc8000 346 | SENDBYTE 1 "%ABS_FILE%" 347 | origin = 0x1774000 348 | destination = 0xdd8000 349 | SENDBYTE 1 "%ABS_FILE%" 350 | origin = 0x1778000 351 | destination = 0xde8000 352 | SENDBYTE 1 "%ABS_FILE%" 353 | origin = 0x177c000 354 | destination = 0xdf8000 355 | SENDBYTE 1 "%ABS_FILE%" 356 | origin = 0x1780000 357 | destination = 0xe08000 358 | SENDBYTE 1 "%ABS_FILE%" 359 | origin = 0x1784000 360 | destination = 0xe18000 361 | SENDBYTE 1 "%ABS_FILE%" 362 | origin = 0x1788000 363 | destination = 0xe28000 364 | SENDBYTE 1 "%ABS_FILE%" 365 | origin = 0x178c000 366 | destination = 0xe38000 367 | SENDBYTE 1 "%ABS_FILE%" 368 | origin = 0x1790000 369 | destination = 0xe48000 370 | SENDBYTE 1 "%ABS_FILE%" 371 | origin = 0x1794000 372 | destination = 0xe58000 373 | SENDBYTE 1 "%ABS_FILE%" 374 | origin = 0x1798000 375 | destination = 0xe68000 376 | SENDBYTE 1 "%ABS_FILE%" 377 | origin = 0x179c000 378 | destination = 0xe78000 379 | SENDBYTE 1 "%ABS_FILE%" 380 | origin = 0x17a0000 381 | destination = 0xe88000 382 | SENDBYTE 1 "%ABS_FILE%" 383 | origin = 0x17a4000 384 | destination = 0xe98000 385 | SENDBYTE 1 "%ABS_FILE%" 386 | origin = 0x17a8000 387 | destination = 0xea8000 388 | SENDBYTE 1 "%ABS_FILE%" 389 | origin = 0x17ac000 390 | destination = 0xeb8000 391 | SENDBYTE 1 "%ABS_FILE%" 392 | origin = 0x17b0000 393 | destination = 0xec8000 394 | SENDBYTE 1 "%ABS_FILE%" 395 | origin = 0x17b4000 396 | destination = 0xed8000 397 | SENDBYTE 1 "%ABS_FILE%" 398 | origin = 0x17b8000 399 | destination = 0xee8000 400 | SENDBYTE 1 "%ABS_FILE%" 401 | origin = 0x17bc000 402 | destination = 0xef8000 403 | SENDBYTE 1 "%ABS_FILE%" 404 | origin = 0x17c0000 405 | destination = 0xf08000 406 | SENDBYTE 1 "%ABS_FILE%" 407 | origin = 0x17c4000 408 | destination = 0xf18000 409 | SENDBYTE 1 "%ABS_FILE%" 410 | origin = 0x17c8000 411 | destination = 0xf28000 412 | SENDBYTE 1 "%ABS_FILE%" 413 | origin = 0x17cc000 414 | destination = 0xf38000 415 | SENDBYTE 1 "%ABS_FILE%" 416 | origin = 0x17d0000 417 | destination = 0xf48000 418 | SENDBYTE 1 "%ABS_FILE%" 419 | origin = 0x17d4000 420 | destination = 0xf58000 421 | SENDBYTE 1 "%ABS_FILE%" 422 | origin = 0x17d8000 423 | destination = 0xf68000 424 | SENDBYTE 1 "%ABS_FILE%" 425 | origin = 0x17dc000 426 | destination = 0xf78000 427 | SENDBYTE 1 "%ABS_FILE%" 428 | origin = 0x17e0000 429 | destination = 0xf88000 430 | SENDBYTE 1 "%ABS_FILE%" 431 | origin = 0x17e4000 432 | destination = 0xf98000 433 | SENDBYTE 1 "%ABS_FILE%" 434 | origin = 0x17e8000 435 | destination = 0xfa8000 436 | SENDBYTE 1 "%ABS_FILE%" 437 | origin = 0x17ec000 438 | destination = 0xfb8000 439 | SENDBYTE 1 "%ABS_FILE%" 440 | origin = 0x17f0000 441 | destination = 0xfc8000 442 | SENDBYTE 1 "%ABS_FILE%" 443 | origin = 0x17f4000 444 | destination = 0xfd8000 445 | SENDBYTE 1 "%ABS_FILE%" 446 | origin = 0x17f8000 447 | destination = 0xfe8000 448 | SENDBYTE 1 "%ABS_FILE%" 449 | origin = 0x17fc000 450 | destination = 0xff8000 451 | SENDBYTE 1 "%ABS_FILE%" 452 | 453 | CLOSE 454 | -------------------------------------------------------------------------------- /Project/prm/S12X.prm: -------------------------------------------------------------------------------- 1 | /* This is a linker parameter file for the MC9S12XET256 */ 2 | 3 | /* 4 | This file is setup to use the HCS12X core only. 5 | If you plan to also use the XGATE in your project, best create a new project with the 6 | 'New Project Wizard' (File|New... menu in the CodeWarrior IDE) and choose the appropriate 7 | project parameters. 8 | */ 9 | 10 | NAMES 11 | /* CodeWarrior will pass all the needed files to the linker by command line. But here you may add your additional files */ 12 | END 13 | 14 | SEGMENTS /* here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. All addresses are 'logical' */ 15 | /* Register space */ 16 | /* IO_SEG = PAGED 0x0000 TO 0x07FF; intentionally not defined */ 17 | 18 | /* non-paged EEPROM */ 19 | EEPROM = READ_ONLY DATA_NEAR IBCC_NEAR 0x0C00 TO 0x0FFF; 20 | 21 | /* non-paged RAM */ 22 | STACK_AREA = READ_WRITE DATA_NEAR 0x2002 TO 0x27FF; 23 | RAM = READ_WRITE DATA_NEAR 0x2800 TO 0x3FFF; 24 | 25 | /* non-banked FLASH */ 26 | /*ROM_4000 = READ_ONLY DATA_NEAR IBCC_NEAR 0x4000 TO 0x7FFF;*/ 27 | ROM_C000 = READ_ONLY DATA_NEAR IBCC_NEAR 0xC000 TO 0xFEFF; 28 | /* VECTORS = READ_ONLY 0xFF00 TO 0xFFFF; intentionally not defined: used for VECTOR commands below */ 29 | //OSVECTORS = READ_ONLY 0xFF10 TO 0xFFFF; /* OSEK interrupt vectors (use your vector.o) */ 30 | 31 | /* paged EEPROM 0x0800 TO 0x0BFF; addressed through EPAGE */ 32 | EEPROM_00 = READ_ONLY DATA_FAR IBCC_FAR 0x000800 TO 0x000BFF; 33 | EEPROM_01 = READ_ONLY DATA_FAR IBCC_FAR 0x010800 TO 0x010BFF; 34 | EEPROM_02 = READ_ONLY DATA_FAR IBCC_FAR 0x020800 TO 0x020BFF; 35 | EEPROM_03 = READ_ONLY DATA_FAR IBCC_FAR 0x030800 TO 0x030BFF; 36 | EEPROM_04 = READ_ONLY DATA_FAR IBCC_FAR 0x040800 TO 0x040BFF; 37 | EEPROM_05 = READ_ONLY DATA_FAR IBCC_FAR 0x050800 TO 0x050BFF; 38 | EEPROM_06 = READ_ONLY DATA_FAR IBCC_FAR 0x060800 TO 0x060BFF; 39 | EEPROM_07 = READ_ONLY DATA_FAR IBCC_FAR 0x070800 TO 0x070BFF; 40 | EEPROM_08 = READ_ONLY DATA_FAR IBCC_FAR 0x080800 TO 0x080BFF; 41 | EEPROM_09 = READ_ONLY DATA_FAR IBCC_FAR 0x090800 TO 0x090BFF; 42 | EEPROM_0A = READ_ONLY DATA_FAR IBCC_FAR 0x0A0800 TO 0x0A0BFF; 43 | EEPROM_0B = READ_ONLY DATA_FAR IBCC_FAR 0x0B0800 TO 0x0B0BFF; 44 | EEPROM_0C = READ_ONLY DATA_FAR IBCC_FAR 0x0C0800 TO 0x0C0BFF; 45 | EEPROM_0D = READ_ONLY DATA_FAR IBCC_FAR 0x0D0800 TO 0x0D0BFF; 46 | EEPROM_0E = READ_ONLY DATA_FAR IBCC_FAR 0x0E0800 TO 0x0E0BFF; 47 | EEPROM_0F = READ_ONLY DATA_FAR IBCC_FAR 0x0F0800 TO 0x0F0BFF; 48 | EEPROM_10 = READ_ONLY DATA_FAR IBCC_FAR 0x100800 TO 0x100BFF; 49 | EEPROM_11 = READ_ONLY DATA_FAR IBCC_FAR 0x110800 TO 0x110BFF; 50 | EEPROM_12 = READ_ONLY DATA_FAR IBCC_FAR 0x120800 TO 0x120BFF; 51 | EEPROM_13 = READ_ONLY DATA_FAR IBCC_FAR 0x130800 TO 0x130BFF; 52 | EEPROM_14 = READ_ONLY DATA_FAR IBCC_FAR 0x140800 TO 0x140BFF; 53 | EEPROM_15 = READ_ONLY DATA_FAR IBCC_FAR 0x150800 TO 0x150BFF; 54 | EEPROM_16 = READ_ONLY DATA_FAR IBCC_FAR 0x160800 TO 0x160BFF; 55 | EEPROM_17 = READ_ONLY DATA_FAR IBCC_FAR 0x170800 TO 0x170BFF; 56 | EEPROM_18 = READ_ONLY DATA_FAR IBCC_FAR 0x180800 TO 0x180BFF; 57 | EEPROM_19 = READ_ONLY DATA_FAR IBCC_FAR 0x190800 TO 0x190BFF; 58 | EEPROM_1A = READ_ONLY DATA_FAR IBCC_FAR 0x1A0800 TO 0x1A0BFF; 59 | EEPROM_1B = READ_ONLY DATA_FAR IBCC_FAR 0x1B0800 TO 0x1B0BFF; 60 | EEPROM_1C = READ_ONLY DATA_FAR IBCC_FAR 0x1C0800 TO 0x1C0BFF; 61 | EEPROM_1D = READ_ONLY DATA_FAR IBCC_FAR 0x1D0800 TO 0x1D0BFF; 62 | EEPROM_1E = READ_ONLY DATA_FAR IBCC_FAR 0x1E0800 TO 0x1E0BFF; 63 | EEPROM_1F = READ_ONLY DATA_FAR IBCC_FAR 0x1F0800 TO 0x1F0BFF; 64 | EEPROM_FC = READ_ONLY DATA_FAR IBCC_FAR 0xFC0800 TO 0xFC0BFF; 65 | EEPROM_FD = READ_ONLY DATA_FAR IBCC_FAR 0xFD0800 TO 0xFD0BFF; 66 | EEPROM_FE = READ_ONLY DATA_FAR IBCC_FAR 0xFE0800 TO 0xFE0BFF; 67 | /* EEPROM_FF = READ_ONLY 0xFF0800 TO 0xFF0BFF; intentionally not defined: equivalent to EEPROM */ 68 | 69 | /* paged RAM: 0x1000 TO 0x1FFF; addressed through RPAGE */ 70 | RAM_FC = READ_WRITE DATA_FAR 0xFC1000 TO 0xFC1FFF; 71 | RAM_FD = READ_WRITE DATA_FAR 0xFD1000 TO 0xFD1FFF; 72 | /* RAM_FE = READ_WRITE 0xFE1000 TO 0xFE1FFF; intentionally not defined: equivalent to RAM: 0x2000..0x2FFF */ 73 | /* RAM_FF = READ_WRITE 0xFF1000 TO 0xFF1FFF; intentionally not defined: equivalent to RAM: 0x3000..0x3FFF */ 74 | 75 | /* paged FLASH: 0x8000 TO 0xBFFF; addressed through PPAGE */ 76 | PAGE_E0 = READ_ONLY DATA_FAR IBCC_FAR 0xE08000 TO 0xE0BFFF; 77 | PAGE_E1 = READ_ONLY DATA_FAR IBCC_FAR 0xE18000 TO 0xE1BFFF; 78 | PAGE_E2 = READ_ONLY DATA_FAR IBCC_FAR 0xE28000 TO 0xE2BFFF; 79 | PAGE_E3 = READ_ONLY DATA_FAR IBCC_FAR 0xE38000 TO 0xE3BFFF; 80 | PAGE_E4 = READ_ONLY DATA_FAR IBCC_FAR 0xE48000 TO 0xE4BFFF; 81 | PAGE_E5 = READ_ONLY DATA_FAR IBCC_FAR 0xE58000 TO 0xE5BFFF; 82 | PAGE_E6 = READ_ONLY DATA_FAR IBCC_FAR 0xE68000 TO 0xE6BFFF; 83 | PAGE_E7 = READ_ONLY DATA_FAR IBCC_FAR 0xE78000 TO 0xE7BFFF; 84 | 85 | PAGE_F8 = READ_ONLY DATA_FAR IBCC_FAR 0xF88000 TO 0xF8BFFF; 86 | PAGE_F9 = READ_ONLY DATA_FAR IBCC_FAR 0xF98000 TO 0xF9BFFF; 87 | PAGE_FA = READ_ONLY DATA_FAR IBCC_FAR 0xFA8000 TO 0xFABFFF; 88 | PAGE_FB = READ_ONLY DATA_FAR IBCC_FAR 0xFB8000 TO 0xFBBFFF; 89 | PAGE_FC = READ_ONLY DATA_FAR IBCC_FAR 0xFC8000 TO 0xFCBFFF; 90 | /* PAGE_FD = READ_ONLY 0xFD8000 TO 0xFDBFFF; intentionally not defined: equivalent to ROM_4000 */ 91 | PAGE_FE = READ_ONLY DATA_FAR IBCC_FAR 0xFE8000 TO 0xFEBFFF; 92 | /* PAGE_FF = READ_ONLY 0xFF8000 TO 0xFFBFFF; intentionally not defined: equivalent to ROM_C000 */ 93 | END 94 | 95 | PLACEMENT /* here all predefined and user segments are placed into the SEGMENTS defined above. */ 96 | _PRESTART, /* Used in HIWARE format: jump to _Startup at the code start */ 97 | STARTUP, /* startup data structures */ 98 | ROM_VAR, /* constant variables */ 99 | STRINGS, /* string literals */ 100 | VIRTUAL_TABLE_SEGMENT, /* C++ virtual table segment */ 101 | //.ostext, /* eventually OSEK code */ 102 | NON_BANKED /* runtime routines which must not be banked */ 103 | /* in case you want to use ROM_4000 here as well, make sure 104 | that all files (incl. library files) are compiled with the 105 | option: -OnB=b */ 106 | INTO ROM_C000/*, ROM_4000*/; 107 | 108 | DEFAULT_ROM, 109 | COPY /* copy down information: how to initialize variables */ 110 | INTO PAGE_FE, PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8, 111 | PAGE_E7, PAGE_E6, PAGE_E5, PAGE_E4, PAGE_E3, PAGE_E2, PAGE_E1, PAGE_E0; 112 | 113 | //.stackstart, /* eventually used for OSEK kernel awareness: Main-Stack Start */ 114 | SSTACK 115 | INTO STACK_AREA; 116 | /* allocate stack first to avoid overwriting variables on overflow */ 117 | //.stackend, /* eventually used for OSEK kernel awareness: Main-Stack End */ 118 | DEFAULT_RAM /* all variables, the default RAM location */ 119 | INTO RAM; 120 | 121 | PAGED_RAM INTO /* when using banked addressing for variable data, make sure to specify 122 | the option -D__FAR_DATA on the compiler command line */ 123 | RAM_FC, RAM_FD; 124 | 125 | DISTRIBUTE DISTRIBUTE_INTO 126 | /*ROM_4000,*/ PAGE_FE, PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8, PAGE_E7, 127 | PAGE_E6, PAGE_E5, PAGE_E4, PAGE_E3, PAGE_E2, PAGE_E1, PAGE_E0; 128 | CONST_DISTRIBUTE DISTRIBUTE_INTO 129 | /*ROM_4000,*/ PAGE_FE, PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8, PAGE_E7, 130 | PAGE_E6, PAGE_E5, PAGE_E4, PAGE_E3, PAGE_E2, PAGE_E1, PAGE_E0; 131 | DATA_DISTRIBUTE DISTRIBUTE_INTO 132 | RAM, RAM_FD, RAM_FC; 133 | //.vectors INTO OSVECTORS; /* OSEK vector table */ 134 | END 135 | 136 | 137 | ENTRIES /* keep the following unreferenced variables */ 138 | /* OSEK: always allocate the vector table and all dependent objects */ 139 | //_vectab OsBuildNumber _OsOrtiStackStart _OsOrtiStart 140 | END 141 | 142 | STACKSIZE 0x7FE /* size of the stack (will be allocated in DEFAULT_RAM) */ 143 | 144 | /* use these definitions in plane of the vector table ('vectors') above */ 145 | VECTOR 0 _Startup /* reset vector: this is the default entry point for a C/C++ application. */ 146 | VECTOR 1 _Startup 147 | VECTOR 2 _Startup -------------------------------------------------------------------------------- /Project/prm/burner.bbl: -------------------------------------------------------------------------------- 1 | /* logical s-record file */ 2 | OPENFILE "%ABS_FILE%.s19" 3 | format=motorola 4 | busWidth=1 5 | origin=0 6 | len=0x1000000 7 | destination=0 8 | SRECORD=Sx 9 | SENDBYTE 1 "%ABS_FILE%" 10 | CLOSE 11 | 12 | /* physical s-record file */ 13 | OPENFILE "%ABS_FILE%.phy" 14 | format = motorola 15 | busWidth = 1 16 | len = 0x4000 17 | 18 | /* logical non banked flash at $4000 and $C000 to physical */ 19 | origin = 0x1000 20 | destination = 0x001000 21 | len = 0x1000 22 | SENDBYTE 1 "%ABS_FILE%" 23 | 24 | origin = 0x004000 25 | destination = 0x34000 26 | len = 0x4000 27 | SENDBYTE 1 "%ABS_FILE%" 28 | 29 | origin = 0x00C000 30 | destination = 0x3C000 31 | len = 0x4000 32 | SENDBYTE 1 "%ABS_FILE%" 33 | 34 | /* logical 96kB banked flash to physical */ 35 | 36 | origin = 0x0A8000 37 | destination = 0x288000 38 | len = 0x4000 39 | SENDBYTE 1 "%ABS_FILE%" 40 | 41 | origin = 0x0B8000 42 | destination = 0x2C000 43 | len = 0x4000 44 | SENDBYTE 1 "%ABS_FILE%" 45 | 46 | origin = 0x0C8000 47 | destination = 0x030000 48 | len = 0x1000 49 | SENDBYTE 1 "%ABS_FILE%" 50 | 51 | origin = 0x0CA000 52 | destination = 0x032000 53 | len = 0x2000 54 | SENDBYTE 1 "%ABS_FILE%" 55 | 56 | origin = 0x0D8000 57 | destination = 0x034000 58 | len = 0x4000 59 | SENDBYTE 1 "%ABS_FILE%" 60 | 61 | origin = 0x0E8000 62 | destination = 0x038000 63 | len = 0x4000 64 | SENDBYTE 1 "%ABS_FILE%" 65 | 66 | origin = 0x0F8000 67 | destination = 0x03C000 68 | len = 0x4000 69 | SENDBYTE 1 "%ABS_FILE%" 70 | 71 | CLOSE 72 | 73 | -------------------------------------------------------------------------------- /S12G-dual-master.npf: -------------------------------------------------------------------------------- 1 | /*** GENERAL DEFINITION ***/ 2 | LIN_node_config_file; 3 | 4 | /*** MCU DEFINITION ***/ 5 | mcu { /* Must check the correct MCU name */ 6 | mcu_name = MC9S12G128; 7 | bus_clock = 24000000; /* Frequency bus of system Hz*/ 8 | xgate_support = no; /* Support XGATE Co-Processor */ 9 | } 10 | 11 | /*** LIN HARDWARE DEFINITION ***/ 12 | /* SCI config */ 13 | sci{ 14 | s12_sci0{ 15 | sci_channel = 0; 16 | } 17 | s12_sci1{ 18 | sci_channel = 1; 19 | } 20 | } 21 | 22 | /*** NETWORK DEFINITION ***/ 23 | network { 24 | idle_timeout = 5s; 25 | diagnostic_class = 1; 26 | max_message_length = 8; 27 | LI0{ 28 | node = EVSE_Master; /* Name of node described in LDF (must check consistence with LDF) */ 29 | file = "J3068-2.ldf"; /* Path to LDF file */ 30 | device = s12_sci0; /* Identifier to LIN Hardware, related to LIN HARDWARE DEFINITION */ 31 | support_sid { 32 | READ_BY_IDENTIFIER = 178; 33 | ASSIGN_FRAME_ID_RANGE = 183; 34 | ASSIGN_NAD = 176; 35 | CONDITIONAL_CHANGE_NAD = 179; 36 | SAVE_CONFIGURATION = 182; 37 | } 38 | } 39 | LI1{ 40 | node = EVSE_Master; /* Name of node described in LDF (must check consistence with LDF) */ 41 | file = "J3068-2B.ldf"; /* Path to LDF file */ 42 | device = s12_sci1; /* Identifier to LIN Hardware, related to LIN HARDWARE DEFINITION */ 43 | support_sid { 44 | READ_BY_IDENTIFIER = 178; 45 | ASSIGN_FRAME_ID_RANGE = 183; 46 | ASSIGN_NAD = 176; 47 | CONDITIONAL_CHANGE_NAD = 179; 48 | SAVE_CONFIGURATION = 182; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /S12G-dual-slave.npf: -------------------------------------------------------------------------------- 1 | /*** GENERAL DEFINITION ***/ 2 | LIN_node_config_file; 3 | 4 | /*** MCU DEFINITION ***/ 5 | mcu { /* Must check the correct MCU name */ 6 | mcu_name = MC9S12G128; 7 | bus_clock = 24000000; /* Frequency bus of system Hz*/ 8 | xgate_support = no; /* Support XGATE Co-Processor */ 9 | } 10 | 11 | /*** LIN HARDWARE DEFINITION ***/ 12 | /* SCI config */ 13 | sci{ 14 | s12_sci0{ 15 | sci_channel = 0; 16 | } 17 | s12_sci1{ 18 | sci_channel = 1; 19 | } 20 | } 21 | 22 | /*** NETWORK DEFINITION ***/ 23 | network { 24 | idle_timeout = 5s; 25 | diagnostic_class = 1; 26 | max_message_length = 8; 27 | LI0{ 28 | node = VehicleAC_charger_slave; /* Name of node described in LDF (must check consistence with LDF) */ 29 | file = "J3068-2.ldf"; /* Path to LDF file */ 30 | device = s12_sci0; /* Identifier to LIN Hardware, related to LIN HARDWARE DEFINITION */ 31 | support_sid { 32 | READ_BY_IDENTIFIER = 178; 33 | ASSIGN_FRAME_ID_RANGE = 183; 34 | ASSIGN_NAD = 176; 35 | CONDITIONAL_CHANGE_NAD = 179; 36 | SAVE_CONFIGURATION = 182; 37 | } 38 | } 39 | LI1{ 40 | node = VehicleAC_charger_slave; /* Name of node described in LDF (must check consistence with LDF) */ 41 | file = "J3068-2B.ldf"; /* Path to LDF file */ 42 | device = s12_sci1; /* Identifier to LIN Hardware, related to LIN HARDWARE DEFINITION */ 43 | support_sid { 44 | READ_BY_IDENTIFIER = 178; 45 | ASSIGN_FRAME_ID_RANGE = 183; 46 | ASSIGN_NAD = 176; 47 | CONDITIONAL_CHANGE_NAD = 179; 48 | SAVE_CONFIGURATION = 182; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /adc_constants.m: -------------------------------------------------------------------------------- 1 | % This Matlab script generates a header file of macros to define maximum and minimum ADC count values for the various Pilot and Prox states. 2 | % It has been tested to work correctly in Octave. It calculates the values based on the resistor network used to attenuate and shift 3 | % the Pilot signal, and the Prox resistor network defined in section 6.2 of J3068 (Ed. 1). 4 | 5 | clear all; 6 | 7 | HeaderFile = 'adc_constants.h'; 8 | FilePath = 'Project/Sources/'; 9 | 10 | %All 11 | global Vsup = 5; %Supply voltage of ADC 12 | global Bits = 8; %ADC resolution 13 | global Type = @uint8; %smallest standard type the ADC resolution fits in 14 | 15 | %Pilot 16 | global Rsup = 62e3; %Resistor between the supply and ADC input 17 | global Rgnd = 91e3; %Resistor between the ADC input and ground 18 | global Rseries = 200e3; %Resistor between the Pilot signal and the ADC input 19 | 20 | 21 | StateANominal = 12; 22 | StateAPlus = StateAMinus = 1; %Emperical additive tolerance on Pilot state values 23 | StateBNominal = 9; 24 | StateBPlus = StateBMinus = 1; 25 | StateCNominal = 6; 26 | StateCPlus = StateCMinus = 1.3; 27 | StateENominal = 0; 28 | StateEPlus = StateEMinus = 1.2; 29 | StateFNominal = -12; 30 | StateFPlus = 1; 31 | StateFMinus = 1.2; 32 | %These are not used in J3068 33 | StateDNominal = 3; 34 | StateDPlus = StateDMinus = 1; 35 | StateRNominal = -5.3; 36 | StateRPlus = StateRMinus = 1; 37 | 38 | 39 | %Prox 40 | global J1772ResTol = 10; %Tolerance (%) of resistors in the standard/J1772 Prox circuit 41 | J1772ExtraTol = 15; %Tolerance (%) on computed value (power supply, etc.) 42 | 43 | IECResTol = 3; %Tolerance (%) of resistors in the J3068/61581-Annex-D Prox Circuit 44 | 45 | global FileHandle = fopen([FilePath HeaderFile],'w'); 46 | 47 | function Vout = DividerVoltage( Vin ) 48 | global Vsup Rsup Rgnd Rseries 49 | Vout = (Rsup*Rgnd*Vin + Rseries*Rgnd*Vsup)/(Rsup*Rgnd + Rseries*Rgnd + Rseries*Rsup); 50 | end 51 | 52 | function Counts = ADCcounts( Vin ) 53 | global Vsup Bits Type 54 | Counts = Type( (Vin/Vsup) * (2^Bits - 1)); 55 | end 56 | 57 | function out = ConstCalc( Vin ) 58 | out = ADCcounts(DividerVoltage(Vin)); 59 | end 60 | 61 | function _DefinePilot( State, Limit, Voltage) 62 | global FileHandle 63 | 64 | fprintf(FileHandle, '#define %-35s 0x%02X // %d V\n', ['STATE_' State, '_', Limit], ConstCalc(Voltage), Voltage) 65 | end 66 | 67 | function DefinePilot( State, Nom, Plus, Minus) 68 | global FileHandle 69 | 70 | _DefinePilot(State, 'MAX', Nom+Plus) 71 | _DefinePilot(State, 'NOM', Nom) 72 | _DefinePilot(State, 'MIN', Nom-Minus) 73 | fprintf(FileHandle, '\n'); 74 | end 75 | 76 | function R = par( r1, r2 ) 77 | R = r1*r2/(r1+r2); 78 | end 79 | 80 | 81 | function V = ProxV( r6, tolerance, dir, J1772) %tolerance in percent, dir is boolean true skews high 82 | global J1772ResTol 83 | int_J1772ResTol = J1772ResTol/100; 84 | 85 | tolerance = tolerance/100; 86 | low = 1-tolerance; 87 | high = 1+tolerance; 88 | if dir 89 | pos = high; 90 | neg = low; 91 | else 92 | pos = low; 93 | neg = high; 94 | end 95 | r4 = neg*330; 96 | r5 = pos*2700; 97 | if J1772 98 | if dir 99 | r6 = (1+int_J1772ResTol)*r6; 100 | else 101 | r6 = (1-int_J1772ResTol)*r6; 102 | end 103 | else 104 | r6 = pos*r6; 105 | end 106 | rl = par(r5, r6); 107 | V = (rl/(r4+rl)); 108 | end 109 | 110 | function __DefineProx( Ident, Limit, Value ) 111 | global FileHandle Bits Vsup 112 | 113 | fprintf(FileHandle, '#define %-35s 0x%02X // %d V\n', [Ident, '_', Limit], Value , (double(Value)/(2^Bits -1))*Vsup) 114 | end 115 | 116 | function _DefineProx( Ident, min, max ) 117 | global FileHandle 118 | 119 | __DefineProx( Ident, 'MAX', max ) 120 | __DefineProx( Ident, 'MIN', min ) 121 | fprintf(FileHandle, '\n') 122 | end 123 | 124 | function DefineProx( Ident, r6, tolerance, J1772, ExtraTol) 125 | global Bits Type 126 | 127 | ExtraTol = ExtraTol/100; 128 | lowP = 1-ExtraTol; 129 | highP = 1+ExtraTol; 130 | 131 | high = ProxV( r6, tolerance, true, J1772)*highP; 132 | low = ProxV( r6, tolerance, false, J1772)*lowP; 133 | 134 | _DefineProx( Ident, Type( low * (2^Bits -1) ), Type( high * (2^Bits -1) ) ) 135 | end 136 | 137 | function out = SplitDiff( Low, High ) 138 | out = Low + ((High - Low) / 2); 139 | end 140 | 141 | GuardString = upper(HeaderFile); 142 | GuardString(end-1) = '_'; 143 | GuardString = ['_' GuardString]; 144 | 145 | %header guard 146 | fprintf(FileHandle, ['#ifndef ' GuardString '\n'] ); 147 | fprintf(FileHandle, ['#define ' GuardString '\n'] ); 148 | 149 | fprintf(FileHandle, '\n// This file is generated by adc_constants.m \n\n'); 150 | 151 | % Pilot section 152 | % States D and R are not used in J3068 153 | fprintf(FileHandle, '\n// MIN/MAX Values for the Pilot states\n'); 154 | DefinePilot('A', StateANominal, StateAPlus, StateAMinus); 155 | DefinePilot('B', StateBNominal, StateBPlus, StateBMinus); 156 | DefinePilot('C', StateCNominal, StateCPlus, StateCMinus); 157 | DefinePilot('D', StateDNominal, StateDPlus, StateDMinus); 158 | DefinePilot('E', StateENominal, StateEPlus, StateEMinus); 159 | DefinePilot('R', StateRNominal, StateRPlus, StateRMinus); 160 | DefinePilot('F', StateFNominal, StateFPlus, StateFMinus); 161 | 162 | % Prox section 163 | % Nominal values are not generated as they aren't used. 164 | fprintf(FileHandle, '\n// MIN/MAX Values for the Prox states\n'); 165 | fprintf(FileHandle, '// Standard prox is not used in J3068, but the code is capable of handling it so we might as well define the values.\n') 166 | 167 | DefineProx( 'PROX_STATE_DISCONNECTED', 100000000000000000, J1772ResTol, false, J1772ExtraTol) %Use a very large value for "infinite" R6 A.K.A. disconnected 168 | DefineProx( 'PROX_STATE_CONNECTED_OFF', 150+330, J1772ResTol, false, J1772ExtraTol) 169 | DefineProx( 'PROX_STATE_CONNECTED_ON', 150, J1772ResTol, false, J1772ExtraTol) 170 | fprintf(FileHandle, '\n') 171 | 172 | fprintf(FileHandle, '// J3068/61581-Annex-D Prox\n') 173 | % Calculate nominal fraction of power supply of the edges of each state 174 | IECDisconnectedMaxRaw = ProxV(100000000000000000, IECResTol, true, false); 175 | IECDisconnectedMinRaw = ProxV(100000000000000000, IECResTol, false, false); 176 | IECReservedHighMaxRaw = ProxV(3520, IECResTol, true, false); 177 | IECReservedHighMinRaw = ProxV(3300, IECResTol, false, false); 178 | IEC13AMaxRaw = ProxV(1500, IECResTol, true, false); 179 | IEC13AMinRaw = ProxV(1500, IECResTol, false, false); 180 | IEC20AMaxRaw = ProxV(680, IECResTol, true, false); 181 | IEC20AMinRaw = ProxV(680, IECResTol, false, false); 182 | IECReservedButtonDownMaxRaw = ProxV(150+330, IECResTol, true, true); 183 | IECReservedButtonDownMinRaw = ProxV(150+330, IECResTol, false, true); 184 | IEC32AMaxRaw = ProxV(220, IECResTol, true, false); 185 | IEC32AMinRaw = ProxV(220, IECResTol, false, false); 186 | IECReservedButtonUpMaxRaw = ProxV(150, IECResTol, true, true); 187 | IECReservedButtonUpMinRaw = ProxV(150, IECResTol, false, true); 188 | IEC63AMaxRaw = ProxV(100, IECResTol, true, false)*1.1; %extra tolerance for noisiest state. if modified, check it does not overlap adjacent. 189 | IEC63AMinRaw = ProxV(100, IECResTol, false, false)*.9; 190 | IECReservedLowMaxRaw = ProxV( par(3520, 68), IECResTol, true, false); 191 | IECReservedLowMinRaw = ProxV( par(100, 68), IECResTol, false, false); 192 | 193 | % Find the point between adjacent vlaues calculated in the previous step 194 | IECDisconnectedErrorHigh = SplitDiff(IECDisconnectedMaxRaw, 1); 195 | IECReservedHighDisconnected = SplitDiff(IECReservedHighMaxRaw, IECDisconnectedMinRaw); 196 | IEC13AReservedHigh = SplitDiff(IEC13AMaxRaw, IECReservedHighMinRaw); 197 | IEC20A13A = SplitDiff(IEC20AMaxRaw, IEC13AMinRaw); 198 | IECReservedButtonDown20A = SplitDiff(IECReservedButtonDownMaxRaw, IEC20AMinRaw); 199 | IEC32AReservedButtonDown = SplitDiff(IEC32AMaxRaw, IECReservedButtonDownMinRaw); 200 | IECReservedButtonUp32A = SplitDiff(IECReservedButtonUpMaxRaw, IEC32AMinRaw); 201 | IEC63AReservedButtonUp = SplitDiff(IEC63AMaxRaw, IECReservedButtonUpMinRaw); 202 | IECReservedLow63A = SplitDiff(IECReservedLowMaxRaw, IEC63AMinRaw); 203 | IECErrorLowReservedLow = SplitDiff(0, IECReservedLowMinRaw); 204 | 205 | % Calculate counts associated with the last calculation and define the states so they don't overlap 206 | IECErrorHighMin = Type( IECDisconnectedErrorHigh * (2^Bits -1) ); 207 | IECDisconnectedMax = IECErrorHighMin - 1; 208 | IECDisconnectedMin = Type( IECReservedHighDisconnected * (2^Bits -1) ); 209 | IECReservedHighMax = IECDisconnectedMin - 1; 210 | IECReservedHighMin = Type( IEC13AReservedHigh * (2^Bits -1) ); 211 | IEC13AMax = IECReservedHighMin - 1; 212 | IEC13AMin = Type( IEC20A13A * (2^Bits -1) ); 213 | IEC20AMax = IEC13AMin - 1; 214 | IEC20AMin = Type( IECReservedButtonDown20A * (2^Bits -1) ); 215 | IECReservedButtonDownMax = IEC20AMin - 1; 216 | IECReservedButtonDownMin = Type( IEC32AReservedButtonDown * (2^Bits -1) ); 217 | IEC32AMax = IECReservedButtonDownMin - 1; 218 | IEC32AMin = Type( IECReservedButtonUp32A * (2^Bits -1) ); 219 | IECReservedButtonUpMax = IEC32AMin - 1; 220 | IECReservedButtonUpMin = Type( IEC63AReservedButtonUp * (2^Bits -1) ); 221 | IEC63AMax = IECReservedButtonUpMin - 1; 222 | IEC63AMin = Type( IECReservedLow63A * (2^Bits -1) ); 223 | IECReservedLowMax = IEC63AMin - 1; 224 | IECReservedLowMin = Type( IECErrorLowReservedLow * (2^Bits -1) ); 225 | IECErrorLowMax = IECReservedLowMin - 1; 226 | 227 | % Print values to file 228 | __DefineProx( 'IEC_PROX_ERROR_HIGH', 'MIN', IECErrorHighMin) 229 | fprintf(FileHandle, '\n') 230 | _DefineProx( 'IEC_PROX_DISCONNECTED', IECDisconnectedMin, IECDisconnectedMax) 231 | _DefineProx( 'IEC_PROX_RESERVED_HIGH', IECReservedHighMin, IECReservedHighMax) 232 | _DefineProx( 'IEC_PROX_13A', IEC13AMin, IEC13AMax) 233 | _DefineProx( 'IEC_PROX_20A', IEC20AMin, IEC20AMax) 234 | _DefineProx( 'IEC_PROX_RESERVED_BUTTON_DOWN', IECReservedButtonDownMin, IECReservedButtonDownMax) 235 | _DefineProx( 'IEC_PROX_32A', IEC32AMin, IEC32AMax) 236 | _DefineProx( 'IEC_PROX_RESERVED_BUTTON_UP', IECReservedButtonUpMin, IECReservedButtonUpMax) 237 | _DefineProx( 'IEC_PROX_63A', IEC63AMin, IEC63AMax) 238 | _DefineProx( 'IEC_PROX_RESERVED_LOW', IECReservedLowMin, IECReservedLowMax) 239 | __DefineProx( 'IEC_PROX_ERROR_LOW', 'MAX', IECErrorLowMax) 240 | 241 | fprintf(FileHandle, '\n\n#endif\n' ); 242 | 243 | fclose('all'); 244 | 245 | 246 | --------------------------------------------------------------------------------