Racelogic / Mbed 2 deprecated mbed_2517fd

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers drv_canfdspi_api.cpp Source File

drv_canfdspi_api.cpp

00001 /*******************************************************************************
00002  Title: .
00003 
00004   Company:
00005     Microchip Technology Inc.
00006 
00007   File Name:
00008     drv_canfdspi_api.c
00009 
00010   Summary:
00011     .
00012 
00013   Description:
00014     .
00015  *******************************************************************************/
00016 
00017 //DOM-IGNORE-BEGIN
00018 /*******************************************************************************
00019 Copyright (c) 2016 Microchip Technology Inc. and its subsidiaries.  
00020 You may use this software and any derivatives exclusively with Microchip products. 
00021   
00022 THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS".  
00023 NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, 
00024 INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, 
00025 AND FITNESS FOR A PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, 
00026 COMBINATION WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. 
00027 
00028 IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, 
00029 INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER 
00030 RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED 
00031 OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE.  TO THE FULLEST EXTENT ALLOWED BY LAW, 
00032 MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE 
00033 WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
00034 
00035 MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE TERMS.
00036  *******************************************************************************/
00037 //DOM-IGNORE-END
00038 
00039 
00040 // *****************************************************************************
00041 // *****************************************************************************
00042 // Section: Included Files
00043 
00044 #include "drv_canfdspi_api.h"
00045 #include "drv_canfdspi_register.h"
00046 #include "drv_canfdspi_defines.h"
00047 #include "drv_spi.h"
00048 //#include "system_config.h"
00049 //#include <xc.h>
00050 
00051 // *****************************************************************************
00052 // *****************************************************************************
00053 // Section: Defines
00054 
00055 #define CRCBASE    0xFFFF
00056 #define CRCUPPER   1
00057 
00058 #define SPI_DEFAULT_BUFFER_LENGTH 64
00059 
00060 // *****************************************************************************
00061 // *****************************************************************************
00062 // Section: Variables
00063 
00064 //! SPI Transmit buffer
00065 uint8_t spiTransmitBuffer[SPI_DEFAULT_BUFFER_LENGTH];
00066 
00067 //! SPI Receive buffer
00068 uint8_t spiReceiveBuffer[SPI_DEFAULT_BUFFER_LENGTH];
00069 
00070 //! Reverse order of bits in byte
00071 const uint8_t BitReverseTable256[256] = {
00072     0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
00073     0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
00074     0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
00075     0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
00076     0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
00077     0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
00078     0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
00079     0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
00080     0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
00081     0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
00082     0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
00083     0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
00084     0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
00085     0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
00086     0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
00087     0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
00088 };
00089 
00090 //! Look-up table for CRC calculation
00091 const uint16_t crc16_table[256] = {
00092     0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
00093     0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
00094     0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
00095     0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
00096     0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
00097     0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
00098     0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
00099     0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
00100     0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
00101     0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
00102     0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
00103     0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
00104     0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
00105     0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
00106     0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
00107     0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
00108     0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
00109     0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
00110     0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
00111     0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
00112     0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
00113     0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
00114     0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
00115     0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
00116     0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
00117     0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
00118     0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
00119     0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
00120     0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
00121     0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
00122     0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
00123     0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
00124 };
00125 
00126 
00127 // *****************************************************************************
00128 // *****************************************************************************
00129 // Section: Reset
00130 
00131 int8_t DRV_CANFDSPI_Reset(CANFDSPI_MODULE_ID index)
00132 {
00133     uint16_t spiTransferSize = 2;
00134     int8_t spiTransferError = 0;
00135 
00136     // Compose command
00137     spiTransmitBuffer[0] = (uint8_t) (cINSTRUCTION_RESET << 4);
00138     spiTransmitBuffer[1] = 0;
00139 
00140     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00141 
00142     return spiTransferError;
00143 }
00144 
00145 
00146 // *****************************************************************************
00147 // *****************************************************************************
00148 // Section: SPI Access Functions
00149 
00150 int8_t DRV_CANFDSPI_ReadByte(CANFDSPI_MODULE_ID index, uint16_t address, uint8_t *rxd)
00151 {
00152     uint16_t spiTransferSize = 3;
00153     int8_t spiTransferError = 0;
00154 
00155     // Compose command
00156     spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_READ << 4) + ((address >> 8) & 0xF));
00157     spiTransmitBuffer[1] = (uint8_t) (address & 0xFF);
00158     spiTransmitBuffer[2] = 0;
00159 
00160     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00161 
00162     // Update data
00163     *rxd = spiReceiveBuffer[2];
00164 
00165     return spiTransferError;
00166 }
00167 
00168 int8_t DRV_CANFDSPI_WriteByte(CANFDSPI_MODULE_ID index, uint16_t address, uint8_t txd)
00169 {
00170     uint16_t spiTransferSize = 3;
00171     int8_t spiTransferError = 0;
00172 
00173     // Compose command
00174     spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_WRITE << 4) + ((address >> 8) & 0xF));
00175     spiTransmitBuffer[1] = (uint8_t) (address & 0xFF);
00176     spiTransmitBuffer[2] = txd;
00177 
00178     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00179 
00180     return spiTransferError;
00181 }
00182 
00183 int8_t DRV_CANFDSPI_ReadWord(CANFDSPI_MODULE_ID index, uint16_t address, uint32_t *rxd)
00184 {
00185     uint8_t i;
00186     uint32_t x;
00187     uint16_t spiTransferSize = 6;
00188     int8_t spiTransferError = 0;
00189 
00190     // Compose command
00191     spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_READ << 4) + ((address >> 8) & 0xF));
00192     spiTransmitBuffer[1] = (uint8_t) (address & 0xFF);
00193 
00194     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00195     if (spiTransferError) {
00196         return spiTransferError;
00197     }
00198 
00199     // Update data
00200     *rxd = 0;
00201     for (i = 2; i < 6; i++) {
00202         x = (uint32_t) spiReceiveBuffer[i];
00203         *rxd += x << ((i - 2)*8);
00204     }
00205 
00206     return spiTransferError;
00207 }
00208 
00209 int8_t DRV_CANFDSPI_WriteWord(CANFDSPI_MODULE_ID index, uint16_t address,
00210         uint32_t txd)
00211 {
00212     uint8_t i;
00213     uint16_t spiTransferSize = 6;
00214     int8_t spiTransferError = 0;
00215 
00216     // Compose command
00217     spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_WRITE << 4) + ((address >> 8) & 0xF));
00218     spiTransmitBuffer[1] = (uint8_t) (address & 0xFF);
00219 
00220     // Split word into 4 bytes and add them to buffer
00221     for (i = 0; i < 4; i++) {
00222         spiTransmitBuffer[i + 2] = (uint8_t) ((txd >> (i * 8)) & 0xFF);
00223     }
00224 
00225     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00226 
00227     return spiTransferError;
00228 }
00229 
00230 int8_t DRV_CANFDSPI_ReadHalfWord(CANFDSPI_MODULE_ID index, uint16_t address, uint16_t *rxd)
00231 {
00232     uint8_t i;
00233     uint32_t x;
00234     uint16_t spiTransferSize = 4;
00235     int8_t spiTransferError = 0;
00236 
00237     // Compose command
00238     spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_READ << 4) + ((address >> 8) & 0xF));
00239     spiTransmitBuffer[1] = (uint8_t) (address & 0xFF);
00240 
00241     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00242     if (spiTransferError) {
00243         return spiTransferError;
00244     }
00245 
00246     // Update data
00247     *rxd = 0;
00248     for (i = 2; i < 4; i++) {
00249         x = (uint32_t) spiReceiveBuffer[i];
00250         *rxd += x << ((i - 2)*8);
00251     }
00252 
00253     return spiTransferError;
00254 }
00255 
00256 int8_t DRV_CANFDSPI_WriteHalfWord(CANFDSPI_MODULE_ID index, uint16_t address,
00257         uint16_t txd)
00258 {
00259     uint8_t i;
00260     uint16_t spiTransferSize = 4;
00261     int8_t spiTransferError = 0;
00262 
00263     // Compose command
00264     spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_WRITE << 4) + ((address >> 8) & 0xF));
00265     spiTransmitBuffer[1] = (uint8_t) (address & 0xFF);
00266 
00267     // Split word into 2 bytes and add them to buffer
00268     for (i = 0; i < 2; i++) {
00269         spiTransmitBuffer[i + 2] = (uint8_t) ((txd >> (i * 8)) & 0xFF);
00270     }
00271 
00272     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00273 
00274     return spiTransferError;
00275 }
00276 
00277 int8_t DRV_CANFDSPI_WriteByteSafe(CANFDSPI_MODULE_ID index, uint16_t address,
00278         uint8_t txd)
00279 {
00280     uint16_t crcResult = 0;
00281     uint16_t spiTransferSize = 5;
00282     int8_t spiTransferError = 0;
00283 
00284     // Compose command
00285     spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_WRITE_SAFE << 4) + ((address >> 8) & 0xF));
00286     spiTransmitBuffer[1] = (uint8_t) (address & 0xFF);
00287     spiTransmitBuffer[2] = txd;
00288 
00289     // Add CRC
00290     crcResult = DRV_CANFDSPI_CalculateCRC16(spiTransmitBuffer, 3);
00291     spiTransmitBuffer[3] = (crcResult >> 8) & 0xFF;
00292     spiTransmitBuffer[4] = crcResult & 0xFF;
00293 
00294     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00295 
00296     return spiTransferError;
00297 }
00298 
00299 int8_t DRV_CANFDSPI_WriteWordSafe(CANFDSPI_MODULE_ID index, uint16_t address,
00300         uint32_t txd)
00301 {
00302     uint8_t i;
00303     uint16_t crcResult = 0;
00304     uint16_t spiTransferSize = 8;
00305     int8_t spiTransferError = 0;
00306 
00307     // Compose command
00308     spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_WRITE_SAFE << 4) + ((address >> 8) & 0xF));
00309     spiTransmitBuffer[1] = (uint8_t) (address & 0xFF);
00310 
00311     // Split word into 4 bytes and add them to buffer
00312     for (i = 0; i < 4; i++) {
00313         spiTransmitBuffer[i + 2] = (uint8_t) ((txd >> (i * 8)) & 0xFF);
00314     }
00315 
00316     // Add CRC
00317     crcResult = DRV_CANFDSPI_CalculateCRC16(spiTransmitBuffer, 6);
00318     spiTransmitBuffer[6] = (crcResult >> 8) & 0xFF;
00319     spiTransmitBuffer[7] = crcResult & 0xFF;
00320 
00321     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00322 
00323     return spiTransferError;
00324 }
00325 
00326 int8_t DRV_CANFDSPI_ReadByteArray(CANFDSPI_MODULE_ID index, uint16_t address,
00327         uint8_t *rxd, uint16_t nBytes)
00328 {
00329     uint16_t i;
00330     uint16_t spiTransferSize = nBytes + 2;
00331     int8_t spiTransferError = 0;
00332 
00333     // Compose command
00334     spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_READ << 4) + ((address >> 8) & 0xF));
00335     spiTransmitBuffer[1] = (uint8_t) (address & 0xFF);
00336 
00337     // Clear data
00338     for (i = 2; i < spiTransferSize; i++) {
00339         spiTransmitBuffer[i] = 0;
00340     }
00341 
00342     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00343 
00344     // Update data
00345     for (i = 0; i < nBytes; i++) {
00346         rxd[i] = spiReceiveBuffer[i + 2];
00347     }
00348 
00349     return spiTransferError;
00350 }
00351 
00352 int8_t DRV_CANFDSPI_ReadByteArrayWithCRC(CANFDSPI_MODULE_ID index, uint16_t address,
00353         uint8_t *rxd, uint16_t nBytes, bool fromRam, bool* crcIsCorrect)
00354 {
00355     uint8_t i;
00356     uint16_t crcFromSpiSlave = 0;
00357     uint16_t crcAtController = 0;
00358     uint16_t spiTransferSize = nBytes + 5; //first two bytes for sending command & address, third for size, last two bytes for CRC
00359     int8_t spiTransferError = 0;
00360 
00361     // Compose command
00362     spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_READ_CRC << 4) + ((address >> 8) & 0xF));
00363     spiTransmitBuffer[1] = (uint8_t) (address & 0xFF);
00364     if (fromRam) {
00365         spiTransmitBuffer[2] = nBytes >> 2;
00366     } else {
00367         spiTransmitBuffer[2] = nBytes;
00368     }
00369 
00370     // Clear data
00371     for (i = 3; i < spiTransferSize; i++) {
00372         spiTransmitBuffer[i] = 0;
00373     }
00374 
00375     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00376     if (spiTransferError) {
00377         return spiTransferError;
00378     }
00379 
00380     // Get CRC from controller
00381     crcFromSpiSlave = (uint16_t) (spiReceiveBuffer[spiTransferSize - 2] << 8) + (uint16_t) (spiReceiveBuffer[spiTransferSize - 1]);
00382 
00383     // Use the receive buffer to calculate CRC
00384     // First three bytes need to be command
00385     spiReceiveBuffer[0] = spiTransmitBuffer[0];
00386     spiReceiveBuffer[1] = spiTransmitBuffer[1];
00387     spiReceiveBuffer[2] = spiTransmitBuffer[2];
00388     crcAtController = DRV_CANFDSPI_CalculateCRC16(spiReceiveBuffer, nBytes + 3);
00389 
00390     // Compare CRC readings
00391     if (crcFromSpiSlave == crcAtController) {
00392         *crcIsCorrect = true;
00393     } else {
00394         *crcIsCorrect = false;
00395     }
00396 
00397     // Update data
00398     for (i = 0; i < nBytes; i++) {
00399         rxd[i] = spiReceiveBuffer[i + 3];
00400     }
00401 
00402     return spiTransferError;
00403 }
00404 
00405 int8_t DRV_CANFDSPI_WriteByteArray(CANFDSPI_MODULE_ID index, uint16_t address,
00406         uint8_t *txd, uint16_t nBytes)
00407 {
00408     uint16_t i;
00409     uint16_t spiTransferSize = nBytes + 2;
00410     int8_t spiTransferError = 0;
00411 
00412     // Compose command
00413     spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_WRITE << 4) + ((address >> 8) & 0xF));
00414     spiTransmitBuffer[1] = (uint8_t) (address & 0xFF);
00415 
00416     // Add data
00417     for (i = 2; i < spiTransferSize; i++) {
00418         spiTransmitBuffer[i] = txd[i - 2];
00419     }
00420 
00421     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00422 
00423     return spiTransferError;
00424 }
00425 
00426 int8_t DRV_CANFDSPI_WriteByteArrayWithCRC(CANFDSPI_MODULE_ID index, uint16_t address,
00427         uint8_t *txd, uint16_t nBytes, bool fromRam)
00428 {
00429     uint16_t i;
00430     uint16_t crcResult = 0;
00431     uint16_t spiTransferSize = nBytes + 5;
00432     int8_t spiTransferError = 0;
00433 
00434     // Compose command
00435     spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_WRITE_CRC << 4) + ((address >> 8) & 0xF));
00436     spiTransmitBuffer[1] = (uint8_t) (address & 0xFF);
00437     if (fromRam) {
00438         spiTransmitBuffer[2] = nBytes >> 2;
00439     } else {
00440         spiTransmitBuffer[2] = nBytes;
00441     }
00442 
00443     // Add data
00444     for (i = 0; i < nBytes; i++) {
00445         spiTransmitBuffer[i + 3] = txd[i];
00446     }
00447 
00448     // Add CRC
00449     crcResult = DRV_CANFDSPI_CalculateCRC16(spiTransmitBuffer, spiTransferSize - 2);
00450     spiTransmitBuffer[spiTransferSize - 2] = (uint8_t) ((crcResult >> 8) & 0xFF);
00451     spiTransmitBuffer[spiTransferSize - 1] = (uint8_t) (crcResult & 0xFF);
00452 
00453     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00454 
00455     return spiTransferError;
00456 }
00457 
00458 int8_t DRV_CANFDSPI_ReadWordArray(CANFDSPI_MODULE_ID index, uint16_t address,
00459         uint32_t *rxd, uint16_t nWords)
00460 {
00461     uint16_t i, j, n;
00462     REG_t w;
00463     uint16_t spiTransferSize = nWords * 4 + 2;
00464     int8_t spiTransferError = 0;
00465 
00466     // Compose command
00467     spiTransmitBuffer[0] = (cINSTRUCTION_READ << 4) + ((address >> 8) & 0xF);
00468     spiTransmitBuffer[1] = address & 0xFF;
00469 
00470     // Clear data
00471     for (i = 2; i < spiTransferSize; i++) {
00472         spiTransmitBuffer[i] = 0;
00473     }
00474 
00475     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00476     if (spiTransferError) {
00477         return spiTransferError;
00478     }
00479 
00480     // Convert Byte array to Word array
00481     n = 2;
00482     for (i = 0; i < nWords; i++) {
00483         w.word = 0;
00484         for (j = 0; j < 4; j++, n++) {
00485             w.byte[j] = spiReceiveBuffer[n];
00486         }
00487         rxd[i] = w.word;
00488     }
00489 
00490     return spiTransferError;
00491 }
00492 
00493 int8_t DRV_CANFDSPI_WriteWordArray(CANFDSPI_MODULE_ID index, uint16_t address,
00494         uint32_t *txd, uint16_t nWords)
00495 {
00496     uint16_t i, j, n;
00497     REG_t w;
00498     uint16_t spiTransferSize = nWords * 4 + 2;
00499     int8_t spiTransferError = 0;
00500 
00501     // Compose command
00502     spiTransmitBuffer[0] = (cINSTRUCTION_WRITE << 4) + ((address >> 8) & 0xF);
00503     spiTransmitBuffer[1] = address & 0xFF;
00504 
00505     // Convert ByteArray to word array
00506     n = 2;
00507     for (i = 0; i < nWords; i++) {
00508         w.word = txd[i];
00509         for (j = 0; j < 4; j++, n++) {
00510             spiTransmitBuffer[n] = w.byte[j];
00511         }
00512     }
00513 
00514     spiTransferError = DRV_SPI_TransferData(index, spiTransmitBuffer, spiReceiveBuffer, spiTransferSize);
00515 
00516     return spiTransferError;
00517 }
00518 
00519 
00520 // *****************************************************************************
00521 // *****************************************************************************
00522 // Section: Configuration
00523 
00524 int8_t DRV_CANFDSPI_Configure(CANFDSPI_MODULE_ID index, CAN_CONFIG* config)
00525 {
00526     REG_CiCON ciCon;
00527     int8_t spiTransferError = 0;
00528 
00529     ciCon.word = canControlResetValues[cREGADDR_CiCON / 4];
00530 
00531     ciCon.bF.DNetFilterCount = config->DNetFilterCount;
00532     ciCon.bF.IsoCrcEnable = config->IsoCrcEnable;
00533     ciCon.bF.ProtocolExceptionEventDisable = config->ProtocolExpectionEventDisable;
00534     ciCon.bF.WakeUpFilterEnable = config->WakeUpFilterEnable;
00535     ciCon.bF.WakeUpFilterTime = config->WakeUpFilterTime;
00536     ciCon.bF.BitRateSwitchDisable = config->BitRateSwitchDisable;
00537     ciCon.bF.RestrictReTxAttempts = config->RestrictReTxAttempts;
00538     ciCon.bF.EsiInGatewayMode = config->EsiInGatewayMode;
00539     ciCon.bF.SystemErrorToListenOnly = config->SystemErrorToListenOnly;
00540     ciCon.bF.StoreInTEF = config->StoreInTEF;
00541     ciCon.bF.TXQEnable = config->TXQEnable;
00542     ciCon.bF.TxBandWidthSharing = config->TxBandWidthSharing;
00543 
00544     spiTransferError = DRV_CANFDSPI_WriteWord(index, cREGADDR_CiCON, ciCon.word);
00545     if (spiTransferError) {
00546         return -1;
00547     }
00548 
00549     return spiTransferError;
00550 }
00551 
00552 int8_t DRV_CANFDSPI_ConfigureObjectReset(CAN_CONFIG* config)
00553 {
00554     REG_CiCON ciCon;
00555     ciCon.word = canControlResetValues[cREGADDR_CiCON / 4];
00556 
00557     config->DNetFilterCount = ciCon.bF.DNetFilterCount;
00558     config->IsoCrcEnable = ciCon.bF.IsoCrcEnable;
00559     config->ProtocolExpectionEventDisable = ciCon.bF.ProtocolExceptionEventDisable;
00560     config->WakeUpFilterEnable = ciCon.bF.WakeUpFilterEnable;
00561     config->WakeUpFilterTime = ciCon.bF.WakeUpFilterTime;
00562     config->BitRateSwitchDisable = ciCon.bF.BitRateSwitchDisable;
00563     config->RestrictReTxAttempts = ciCon.bF.RestrictReTxAttempts;
00564     config->EsiInGatewayMode = ciCon.bF.EsiInGatewayMode;
00565     config->SystemErrorToListenOnly = ciCon.bF.SystemErrorToListenOnly;
00566     config->StoreInTEF = ciCon.bF.StoreInTEF;
00567     config->TXQEnable = ciCon.bF.TXQEnable;
00568     config->TxBandWidthSharing = ciCon.bF.TxBandWidthSharing;
00569 
00570     return 0;
00571 }
00572 
00573 // *****************************************************************************
00574 // *****************************************************************************
00575 // Section: Operating mode
00576 
00577 int8_t DRV_CANFDSPI_OperationModeSelect(CANFDSPI_MODULE_ID index,
00578         CAN_OPERATION_MODE opMode)
00579 {
00580     uint8_t d = 0;
00581     int8_t spiTransferError = 0;
00582 
00583     // Read
00584     spiTransferError = DRV_CANFDSPI_ReadByte(index, cREGADDR_CiCON + 3, &d);
00585     if (spiTransferError) {
00586         return -1;
00587     }
00588 
00589     // Modify
00590     d &= ~0x07;
00591     d |= opMode;
00592 
00593     // Write
00594     spiTransferError = DRV_CANFDSPI_WriteByte(index, cREGADDR_CiCON + 3, d);
00595     if (spiTransferError) {
00596         return -2;
00597     }
00598 
00599     return spiTransferError;
00600 }
00601 
00602 CAN_OPERATION_MODE DRV_CANFDSPI_OperationModeGet(CANFDSPI_MODULE_ID index)
00603 {
00604     uint8_t d = 0;
00605     CAN_OPERATION_MODE mode = CAN_INVALID_MODE;
00606     int8_t spiTransferError = 0;
00607 
00608     // Read Opmode
00609     spiTransferError = DRV_CANFDSPI_ReadByte(index, cREGADDR_CiCON + 2, &d);
00610     if (spiTransferError) {
00611         return CAN_INVALID_MODE;
00612     }
00613 
00614     // Get Opmode bits
00615     d = (d >> 5) & 0x7;
00616 
00617     // Decode Opmode
00618     switch (d) {
00619         case CAN_NORMAL_MODE:
00620             mode = CAN_NORMAL_MODE;
00621             break;
00622         case CAN_SLEEP_MODE:
00623             mode = CAN_SLEEP_MODE;
00624             break;
00625         case CAN_INTERNAL_LOOPBACK_MODE:
00626             mode = CAN_INTERNAL_LOOPBACK_MODE;
00627             break;
00628         case CAN_EXTERNAL_LOOPBACK_MODE:
00629             mode = CAN_EXTERNAL_LOOPBACK_MODE;
00630             break;
00631         case CAN_LISTEN_ONLY_MODE:
00632             mode = CAN_LISTEN_ONLY_MODE;
00633             break;
00634         case CAN_CONFIGURATION_MODE:
00635             mode = CAN_CONFIGURATION_MODE;
00636             break;
00637         case CAN_CLASSIC_MODE:
00638             mode = CAN_CLASSIC_MODE;
00639             break;
00640         case CAN_RESTRICTED_MODE:
00641             mode = CAN_RESTRICTED_MODE;
00642             break;
00643         default:
00644             mode = CAN_INVALID_MODE;
00645             break;
00646     }
00647 
00648     return mode;
00649 }
00650 
00651 // *****************************************************************************
00652 // *****************************************************************************
00653 // Section: CAN Transmit
00654 
00655 int8_t DRV_CANFDSPI_TransmitChannelConfigure(CANFDSPI_MODULE_ID index,
00656         CAN_FIFO_CHANNEL channel, CAN_TX_FIFO_CONFIG* config)
00657 {
00658     int8_t spiTransferError = 0;
00659     uint16_t a = 0;
00660 
00661     // Setup FIFO
00662     REG_CiFIFOCON ciFifoCon;
00663     ciFifoCon.word = canControlResetValues[cREGADDR_CiFIFOCON / 4];
00664     ciFifoCon.txBF.TxEnable = 1;
00665     ciFifoCon.txBF.FifoSize = config->FifoSize;
00666     ciFifoCon.txBF.PayLoadSize = config->PayLoadSize;
00667     ciFifoCon.txBF.TxAttempts = config->TxAttempts;
00668     ciFifoCon.txBF.TxPriority = config->TxPriority;
00669     ciFifoCon.txBF.RTREnable = config->RTREnable;
00670 
00671     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET);
00672 
00673     spiTransferError = DRV_CANFDSPI_WriteWord(index, a, ciFifoCon.word);
00674 
00675     return spiTransferError;
00676 }
00677 
00678 int8_t DRV_CANFDSPI_TransmitChannelConfigureObjectReset(CAN_TX_FIFO_CONFIG* config)
00679 {
00680     REG_CiFIFOCON ciFifoCon;
00681     ciFifoCon.word = canControlResetValues[cREGADDR_CiFIFOCON / 4];
00682 
00683     config->RTREnable = ciFifoCon.txBF.RTREnable;
00684     config->TxPriority = ciFifoCon.txBF.TxPriority;
00685     config->TxAttempts = ciFifoCon.txBF.TxAttempts;
00686     config->FifoSize = ciFifoCon.txBF.FifoSize;
00687     config->PayLoadSize = ciFifoCon.txBF.PayLoadSize;
00688 
00689     return 0;
00690 }
00691 
00692 int8_t DRV_CANFDSPI_TransmitQueueConfigure(CANFDSPI_MODULE_ID index,
00693         CAN_TX_QUEUE_CONFIG* config)
00694 {
00695 #ifndef CAN_TXQUEUE_IMPLEMENTED
00696     config;
00697     return -100;
00698 #else
00699     int8_t spiTransferError = 0;
00700     uint16_t a = 0;
00701 
00702     // Setup FIFO
00703     REG_CiTXQCON ciFifoCon;
00704     ciFifoCon.word = canControlResetValues[cREGADDR_CiFIFOCON / 4];
00705 
00706     ciFifoCon.txBF.TxEnable = 1;
00707     ciFifoCon.txBF.FifoSize = config->FifoSize;
00708     ciFifoCon.txBF.PayLoadSize = config->PayLoadSize;
00709     ciFifoCon.txBF.TxAttempts = config->TxAttempts;
00710     ciFifoCon.txBF.TxPriority = config->TxPriority;
00711 
00712     a = cREGADDR_CiTXQCON;
00713     spiTransferError = DRV_CANFDSPI_WriteWord(index, a, ciFifoCon.word);
00714 
00715     return spiTransferError;
00716 #endif    
00717 }
00718 
00719 int8_t DRV_CANFDSPI_TransmitQueueConfigureObjectReset(CAN_TX_QUEUE_CONFIG* config)
00720 {
00721     REG_CiFIFOCON ciFifoCon;
00722     ciFifoCon.word = canControlResetValues[cREGADDR_CiFIFOCON / 4];
00723 
00724     config->TxPriority = ciFifoCon.txBF.TxPriority;
00725     config->TxAttempts = ciFifoCon.txBF.TxAttempts;
00726     config->FifoSize = ciFifoCon.txBF.FifoSize;
00727     config->PayLoadSize = ciFifoCon.txBF.PayLoadSize;
00728 
00729     return 0;
00730 }
00731 
00732 int8_t DRV_CANFDSPI_TransmitChannelLoad(CANFDSPI_MODULE_ID index,
00733         CAN_FIFO_CHANNEL channel, CAN_TX_MSGOBJ* txObj,
00734         uint8_t *txd, uint32_t txdNumBytes, bool flush)
00735 {
00736     uint16_t a;
00737     uint32_t fifoReg[3];
00738     uint32_t dataBytesInObject;
00739     REG_CiFIFOCON ciFifoCon;
00740     REG_CiFIFOSTA ciFifoSta;
00741     REG_CiFIFOUA ciFifoUa;
00742     int8_t spiTransferError = 0;
00743 
00744     // Get FIFO registers
00745     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET);
00746 
00747     spiTransferError = DRV_CANFDSPI_ReadWordArray(index, a, fifoReg, 3);
00748     if (spiTransferError) {
00749         return -1;
00750     }
00751 
00752     // Check that it is a transmit buffer
00753     ciFifoCon.word = fifoReg[0];
00754     if (!ciFifoCon.txBF.TxEnable) {
00755         return -2;
00756     }
00757 
00758     // Check that DLC is big enough for data
00759     dataBytesInObject = DRV_CANFDSPI_DlcToDataBytes((CAN_DLC) txObj->bF.ctrl.DLC);
00760     if (dataBytesInObject < txdNumBytes) {
00761         return -3;
00762     }
00763 
00764     // Get status
00765     ciFifoSta.word = fifoReg[1];
00766 
00767     // Get address
00768     ciFifoUa.word = fifoReg[2];
00769 #ifdef USERADDRESS_TIMES_FOUR
00770     a = 4 * ciFifoUa.bF.UserAddress;
00771 #else
00772     a = ciFifoUa.bF.UserAddress;
00773 #endif
00774     a += cRAMADDR_START;
00775 
00776     uint8_t txBuffer[MAX_MSG_SIZE];
00777 
00778     txBuffer[0] = txObj->byte[0]; //not using 'for' to reduce no of instructions
00779     txBuffer[1] = txObj->byte[1];
00780     txBuffer[2] = txObj->byte[2];
00781     txBuffer[3] = txObj->byte[3];
00782 
00783     txBuffer[4] = txObj->byte[4];
00784     txBuffer[5] = txObj->byte[5];
00785     txBuffer[6] = txObj->byte[6];
00786     txBuffer[7] = txObj->byte[7];
00787 
00788     uint8_t i;
00789     for (i = 0; i < txdNumBytes; i++) {
00790         txBuffer[i + 8] = txd[i];
00791     }
00792 
00793     // Make sure we write a multiple of 4 bytes to RAM
00794     uint16_t n = 0;
00795     uint8_t j = 0;
00796 
00797     if (txdNumBytes % 4) {
00798         // Need to add bytes
00799         n = 4 - (txdNumBytes % 4);
00800         i = txdNumBytes + 8;
00801 
00802         for (j = 0; j < n; j++) {
00803             txBuffer[i + 8 + j] = 0;
00804         }
00805     }
00806 
00807     spiTransferError = DRV_CANFDSPI_WriteByteArray(index, a, txBuffer, txdNumBytes + 8 + n);
00808     if (spiTransferError) {
00809         return -4;
00810     }
00811 
00812     // Set UINC and TXREQ
00813     spiTransferError = DRV_CANFDSPI_TransmitChannelUpdate(index, channel, flush);
00814     if (spiTransferError) {
00815         return -5;
00816     }
00817 
00818     return spiTransferError;
00819 }
00820 
00821 int8_t DRV_CANFDSPI_TransmitChannelFlush(CANFDSPI_MODULE_ID index,
00822         CAN_FIFO_CHANNEL channel)
00823 {
00824     uint8_t d = 0;
00825     uint16_t a = 0;
00826     int8_t spiTransferError = 0;
00827 
00828     // Address of TXREQ
00829     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET);
00830     a += 1;
00831 
00832     // Set TXREQ
00833     d = 0x02;
00834 
00835     // Write
00836     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, d);
00837 
00838     return spiTransferError;
00839 }
00840 
00841 int8_t DRV_CANFDSPI_TransmitChannelStatusGet(CANFDSPI_MODULE_ID index,
00842         CAN_FIFO_CHANNEL channel, CAN_TX_FIFO_STATUS* status)
00843 {
00844     uint16_t a = 0;
00845     uint32_t sta = 0;
00846     uint32_t fifoReg[2];
00847     REG_CiFIFOSTA ciFifoSta;
00848     REG_CiFIFOCON ciFifoCon;
00849     int8_t spiTransferError = 0;
00850 
00851     // Get FIFO registers
00852     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET);
00853 
00854     spiTransferError = DRV_CANFDSPI_ReadWordArray(index, a, fifoReg, 2);
00855     if (spiTransferError) {
00856         return -1;
00857     }
00858 
00859     // Update data
00860     ciFifoCon.word = fifoReg[0];
00861     ciFifoSta.word = fifoReg[1];
00862 
00863     // Update status
00864     sta = ciFifoSta.byte[0];
00865 
00866     if (ciFifoCon.txBF.TxRequest) {
00867         sta |= CAN_TX_FIFO_TRANSMITTING;
00868     }
00869 
00870     *status = (CAN_TX_FIFO_STATUS) (sta & CAN_TX_FIFO_STATUS_MASK);
00871 
00872     return spiTransferError;
00873 }
00874 
00875 int8_t DRV_CANFDSPI_TransmitChannelReset(CANFDSPI_MODULE_ID index,
00876         CAN_FIFO_CHANNEL channel)
00877 {
00878     return DRV_CANFDSPI_ReceiveChannelReset(index, channel);
00879 }
00880 
00881 int8_t DRV_CANFDSPI_TransmitChannelUpdate(CANFDSPI_MODULE_ID index,
00882         CAN_FIFO_CHANNEL channel, bool flush)
00883 {
00884     uint16_t a;
00885     REG_CiFIFOCON ciFifoCon;
00886     int8_t spiTransferError = 0;
00887 
00888     // Set UINC
00889     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET) + 1; // Byte that contains FRESET
00890     ciFifoCon.word = 0;
00891     ciFifoCon.txBF.UINC = 1;
00892 
00893     // Set TXREQ
00894     if (flush) {
00895         ciFifoCon.txBF.TxRequest = 1;
00896     }
00897 
00898     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciFifoCon.byte[1]);
00899     if (spiTransferError) {
00900         return -1;
00901     }
00902 
00903     return spiTransferError;
00904 }
00905 
00906 int8_t DRV_CANFDSPI_TransmitRequestSet(CANFDSPI_MODULE_ID index,
00907         CAN_TXREQ_CHANNEL txreq)
00908 {
00909     int8_t spiTransferError = 0;
00910 
00911     // Write TXREQ register
00912     uint32_t w = txreq;
00913 
00914     spiTransferError = DRV_CANFDSPI_WriteWord(index, cREGADDR_CiTXREQ, w);
00915 
00916     return spiTransferError;
00917 }
00918 
00919 int8_t DRV_CANFDSPI_TransmitRequestGet(CANFDSPI_MODULE_ID index,
00920         uint32_t* txreq)
00921 {
00922     int8_t spiTransferError = 0;
00923 
00924     spiTransferError = DRV_CANFDSPI_ReadWord(index, cREGADDR_CiTXREQ, txreq);
00925 
00926     return spiTransferError;
00927 }
00928 
00929 int8_t DRV_CANFDSPI_TransmitChannelAbort(CANFDSPI_MODULE_ID index,
00930         CAN_FIFO_CHANNEL channel)
00931 {
00932     uint16_t a;
00933     uint8_t d;
00934     int8_t spiTransferError = 0;
00935 
00936     // Address
00937     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET);
00938     a += 1; // byte address of TXREQ
00939 
00940     // Clear TXREQ
00941     d = 0x00;
00942 
00943     // Write
00944     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, d);
00945 
00946     return spiTransferError;
00947 }
00948 
00949 int8_t DRV_CANFDSPI_TransmitAbortAll(CANFDSPI_MODULE_ID index)
00950 {
00951     uint8_t d;
00952     int8_t spiTransferError = 0;
00953 
00954     // Read CiCON byte 3
00955     spiTransferError = DRV_CANFDSPI_ReadByte(index, (cREGADDR_CiCON + 3), &d);
00956     if (spiTransferError) {
00957         return -1;
00958     }
00959 
00960     // Modify
00961     d |= 0x8;
00962 
00963     // Write
00964     spiTransferError = DRV_CANFDSPI_WriteByte(index, (cREGADDR_CiCON + 3), d);
00965     if (spiTransferError) {
00966         return -2;
00967     }
00968 
00969     return spiTransferError;
00970 }
00971 
00972 int8_t DRV_CANFDSPI_TransmitBandWidthSharingSet(CANFDSPI_MODULE_ID index,
00973         CAN_TX_BANDWITH_SHARING txbws)
00974 {
00975     uint8_t d = 0;
00976     int8_t spiTransferError = 0;
00977 
00978     // Read CiCON byte 3
00979     spiTransferError = DRV_CANFDSPI_ReadByte(index, (cREGADDR_CiCON + 3), &d);
00980     if (spiTransferError) {
00981         return -1;
00982     }
00983 
00984     // Modify
00985     d &= 0x0f;
00986     d |= (txbws << 4);
00987 
00988     // Write
00989     spiTransferError = DRV_CANFDSPI_WriteByte(index, (cREGADDR_CiCON + 3), d);
00990     if (spiTransferError) {
00991         return -2;
00992     }
00993 
00994     return spiTransferError;
00995 }
00996 
00997 
00998 // *****************************************************************************
00999 // *****************************************************************************
01000 // Section: CAN Receive
01001 
01002 int8_t DRV_CANFDSPI_FilterObjectConfigure(CANFDSPI_MODULE_ID index,
01003         CAN_FILTER filter, CAN_FILTEROBJ_ID* id)
01004 {
01005     uint16_t a;
01006     REG_CiFLTOBJ fObj;
01007     int8_t spiTransferError = 0;
01008 
01009     // Setup
01010     fObj.word = 0;
01011     fObj.bF = *id;
01012     a = cREGADDR_CiFLTOBJ + (filter * CiFILTER_OFFSET);
01013 
01014     spiTransferError = DRV_CANFDSPI_WriteWord(index, a, fObj.word);
01015 
01016     return spiTransferError;
01017 }
01018 
01019 int8_t DRV_CANFDSPI_FilterMaskConfigure(CANFDSPI_MODULE_ID index,
01020         CAN_FILTER filter, CAN_MASKOBJ_ID* mask)
01021 {
01022     uint16_t a;
01023     REG_CiMASK mObj;
01024     int8_t spiTransferError = 0;
01025 
01026     // Setup
01027     mObj.word = 0;
01028     mObj.bF = *mask;
01029     a = cREGADDR_CiMASK + (filter * CiFILTER_OFFSET);
01030 
01031     spiTransferError = DRV_CANFDSPI_WriteWord(index, a, mObj.word);
01032 
01033     return spiTransferError;
01034 }
01035 
01036 int8_t DRV_CANFDSPI_FilterToFifoLink(CANFDSPI_MODULE_ID index,
01037         CAN_FILTER filter, CAN_FIFO_CHANNEL channel, bool enable)
01038 {
01039     uint16_t a;
01040     REG_CiFLTCON_BYTE fCtrl;
01041     int8_t spiTransferError = 0;
01042 
01043     // Enable
01044     if (enable) {
01045         fCtrl.bF.Enable = 1;
01046     } else {
01047         fCtrl.bF.Enable = 0;
01048     }
01049 
01050     // Link
01051     fCtrl.bF.BufferPointer = channel;
01052     a = cREGADDR_CiFLTCON + filter;
01053 
01054     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, fCtrl.byte);
01055 
01056     return spiTransferError;
01057 }
01058 
01059 int8_t DRV_CANFDSPI_FilterEnable(CANFDSPI_MODULE_ID index, CAN_FILTER filter)
01060 {
01061     uint16_t a;
01062     REG_CiFLTCON_BYTE fCtrl;
01063     int8_t spiTransferError = 0;
01064 
01065     // Read
01066     a = cREGADDR_CiFLTCON + filter;
01067 
01068     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &fCtrl.byte);
01069     if (spiTransferError) {
01070         return -1;
01071     }
01072 
01073     // Modify
01074     fCtrl.bF.Enable = 1;
01075 
01076     // Write
01077     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, fCtrl.byte);
01078     if (spiTransferError) {
01079         return -2;
01080     }
01081 
01082     return spiTransferError;
01083 }
01084 
01085 int8_t DRV_CANFDSPI_FilterDisable(CANFDSPI_MODULE_ID index, CAN_FILTER filter)
01086 {
01087     uint16_t a;
01088     REG_CiFLTCON_BYTE fCtrl;
01089     int8_t spiTransferError = 0;
01090 
01091     // Read
01092     a = cREGADDR_CiFLTCON + filter;
01093 
01094     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &fCtrl.byte);
01095     if (spiTransferError) {
01096         return -1;
01097     }
01098 
01099     // Modify
01100     fCtrl.bF.Enable = 0;
01101 
01102     // Write
01103     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, fCtrl.byte);
01104     if (spiTransferError) {
01105         return -2;
01106     }
01107 
01108     return spiTransferError;
01109 }
01110 
01111 int8_t DRV_CANFDSPI_DeviceNetFilterCountSet(CANFDSPI_MODULE_ID index,
01112         CAN_DNET_FILTER_SIZE dnfc)
01113 {
01114     uint8_t d = 0;
01115     int8_t spiTransferError = 0;
01116 
01117     // Read CiCON byte 0
01118     spiTransferError = DRV_CANFDSPI_ReadByte(index, cREGADDR_CiCON, &d);
01119     if (spiTransferError) {
01120         return -1;
01121     }
01122 
01123     // Modify
01124     d &= 0x1f;
01125     d |= dnfc;
01126 
01127     // Write
01128     spiTransferError = DRV_CANFDSPI_WriteByte(index, cREGADDR_CiCON, d);
01129     if (spiTransferError) {
01130         return -2;
01131     }
01132 
01133     return spiTransferError;
01134 }
01135 
01136 int8_t DRV_CANFDSPI_ReceiveChannelConfigure(CANFDSPI_MODULE_ID index,
01137         CAN_FIFO_CHANNEL channel, CAN_RX_FIFO_CONFIG* config)
01138 {
01139     int8_t spiTransferError = 0;
01140     uint16_t a = 0;
01141 
01142 #ifdef CAN_TXQUEUE_IMPLEMENTED
01143     if (channel == CAN_TXQUEUE_CH0) {
01144         return -100;
01145     }
01146 #endif
01147 
01148     // Setup FIFO
01149     REG_CiFIFOCON ciFifoCon;
01150     ciFifoCon.word = canControlResetValues[cREGADDR_CiFIFOCON / 4];
01151 
01152     ciFifoCon.rxBF.TxEnable = 0;
01153     ciFifoCon.rxBF.FifoSize = config->FifoSize;
01154     ciFifoCon.rxBF.PayLoadSize = config->PayLoadSize;
01155     ciFifoCon.rxBF.RxTimeStampEnable = config->RxTimeStampEnable;
01156 
01157     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET);
01158 
01159     spiTransferError = DRV_CANFDSPI_WriteWord(index, a, ciFifoCon.word);
01160 
01161     return spiTransferError;
01162 }
01163 
01164 int8_t DRV_CANFDSPI_ReceiveChannelConfigureObjectReset(CAN_RX_FIFO_CONFIG* config)
01165 {
01166     REG_CiFIFOCON ciFifoCon;
01167     ciFifoCon.word = canControlResetValues[cREGADDR_CiFIFOCON / 4];
01168 
01169     config->FifoSize = ciFifoCon.rxBF.FifoSize;
01170     config->PayLoadSize = ciFifoCon.rxBF.PayLoadSize;
01171     config->RxTimeStampEnable = ciFifoCon.rxBF.RxTimeStampEnable;
01172 
01173     return 0;
01174 }
01175 
01176 int8_t DRV_CANFDSPI_ReceiveChannelStatusGet(CANFDSPI_MODULE_ID index,
01177         CAN_FIFO_CHANNEL channel, CAN_RX_FIFO_STATUS* status)
01178 {
01179     uint16_t a;
01180     REG_CiFIFOSTA ciFifoSta;
01181     int8_t spiTransferError = 0;
01182 
01183     // Read
01184     ciFifoSta.word = 0;
01185     a = cREGADDR_CiFIFOSTA + (channel * CiFIFO_OFFSET);
01186 
01187     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciFifoSta.byte[0]);
01188     if (spiTransferError) {
01189         return -1;
01190     }
01191 
01192     // Update data
01193     *status = (CAN_RX_FIFO_STATUS) (ciFifoSta.byte[0] & 0x0F);
01194 
01195     return spiTransferError;
01196 }
01197 
01198 int8_t DRV_CANFDSPI_ReceiveMessageGet(CANFDSPI_MODULE_ID index,
01199         CAN_FIFO_CHANNEL channel, CAN_RX_MSGOBJ* rxObj,
01200         uint8_t *rxd, uint8_t nBytes)
01201 {
01202     uint8_t n = 0;
01203     uint8_t i = 0;
01204     uint16_t a;
01205     uint32_t fifoReg[3];
01206     REG_CiFIFOCON ciFifoCon;
01207     REG_CiFIFOSTA ciFifoSta;
01208     REG_CiFIFOUA ciFifoUa;
01209     int8_t spiTransferError = 0;
01210 
01211     // Get FIFO registers
01212     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET);
01213 
01214     spiTransferError = DRV_CANFDSPI_ReadWordArray(index, a, fifoReg, 3);
01215     if (spiTransferError) {
01216         return -1;
01217     }
01218 
01219     // Check that it is a receive buffer
01220     ciFifoCon.word = fifoReg[0];
01221     if (ciFifoCon.txBF.TxEnable) {
01222         return -2;
01223     }
01224 
01225     // Get Status
01226     ciFifoSta.word = fifoReg[1];
01227 
01228     // Get address
01229     ciFifoUa.word = fifoReg[2];
01230 #ifdef USERADDRESS_TIMES_FOUR
01231     a = 4 * ciFifoUa.bF.UserAddress;
01232 #else
01233     a = ciFifoUa.bF.UserAddress;
01234 #endif
01235     a += cRAMADDR_START;
01236 
01237     // Number of bytes to read
01238     n = nBytes + 8; // Add 8 header bytes
01239 
01240     if (ciFifoCon.rxBF.RxTimeStampEnable) {
01241         n += 4; // Add 4 time stamp bytes
01242     }
01243 
01244     // Make sure we read a multiple of 4 bytes from RAM
01245     if (n % 4) {
01246         n = n + 4 - (n % 4);
01247     }
01248 
01249     // Read rxObj using one access
01250     uint8_t ba[MAX_MSG_SIZE];
01251 
01252     if (n > MAX_MSG_SIZE) {
01253         n = MAX_MSG_SIZE;
01254     }
01255 
01256     spiTransferError = DRV_CANFDSPI_ReadByteArray(index, a, ba, n);
01257     if (spiTransferError) {
01258         return -3;
01259     }
01260 
01261     // Assign message header
01262     REG_t myReg;
01263 
01264     myReg.byte[0] = ba[0];
01265     myReg.byte[1] = ba[1];
01266     myReg.byte[2] = ba[2];
01267     myReg.byte[3] = ba[3];
01268     rxObj->word[0] = myReg.word;
01269 
01270     myReg.byte[0] = ba[4];
01271     myReg.byte[1] = ba[5];
01272     myReg.byte[2] = ba[6];
01273     myReg.byte[3] = ba[7];
01274     rxObj->word[1] = myReg.word;
01275 
01276     if (ciFifoCon.rxBF.RxTimeStampEnable) {
01277         myReg.byte[0] = ba[8];
01278         myReg.byte[1] = ba[9];
01279         myReg.byte[2] = ba[10];
01280         myReg.byte[3] = ba[11];
01281         rxObj->word[2] = myReg.word;
01282 
01283         // Assign message data
01284         for (i = 0; i < nBytes; i++) {
01285             rxd[i] = ba[i + 12];
01286         }
01287     } else {
01288         rxObj->word[2] = 0;
01289 
01290         // Assign message data
01291         for (i = 0; i < nBytes; i++) {
01292             rxd[i] = ba[i + 8];
01293         }
01294     }
01295 
01296     // UINC channel
01297     spiTransferError = DRV_CANFDSPI_ReceiveChannelUpdate(index, channel);
01298     if (spiTransferError) {
01299         return -4;
01300     }
01301 
01302     return spiTransferError;
01303 }
01304 
01305 int8_t DRV_CANFDSPI_ReceiveChannelReset(CANFDSPI_MODULE_ID index,
01306         CAN_FIFO_CHANNEL channel)
01307 {
01308     uint16_t a = 0;
01309     REG_CiFIFOCON ciFifoCon;
01310     int8_t spiTransferError = 0;
01311 
01312     // Address and data
01313     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET) + 1; // Byte that contains FRESET
01314     ciFifoCon.word = 0;
01315     ciFifoCon.rxBF.FRESET = 1;
01316 
01317     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciFifoCon.byte[1]);
01318 
01319     return spiTransferError;
01320 }
01321 
01322 int8_t DRV_CANFDSPI_ReceiveChannelUpdate(CANFDSPI_MODULE_ID index,
01323         CAN_FIFO_CHANNEL channel)
01324 {
01325     uint16_t a = 0;
01326     REG_CiFIFOCON ciFifoCon;
01327     int8_t spiTransferError = 0;
01328     ciFifoCon.word = 0;
01329 
01330     // Set UINC
01331     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET) + 1; // Byte that contains FRESET
01332     ciFifoCon.rxBF.UINC = 1;
01333 
01334     // Write byte
01335     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciFifoCon.byte[1]);
01336 
01337     return spiTransferError;
01338 }
01339 
01340 // *****************************************************************************
01341 // *****************************************************************************
01342 // Section: Transmit Event FIFO
01343 
01344 int8_t DRV_CANFDSPI_TefStatusGet(CANFDSPI_MODULE_ID index,
01345         CAN_TEF_FIFO_STATUS* status)
01346 {
01347     int8_t spiTransferError = 0;
01348     uint16_t a = 0;
01349 
01350     // Read
01351     REG_CiTEFSTA ciTefSta;
01352     ciTefSta.word = 0;
01353     a = cREGADDR_CiTEFSTA;
01354 
01355     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciTefSta.byte[0]);
01356     if (spiTransferError) {
01357         return -1;
01358     }
01359 
01360     // Update data
01361     *status = (CAN_TEF_FIFO_STATUS) (ciTefSta.byte[0] & CAN_TEF_FIFO_STATUS_MASK);
01362 
01363     return spiTransferError;
01364 }
01365 
01366 int8_t DRV_CANFDSPI_TefMessageGet(CANFDSPI_MODULE_ID index,
01367         CAN_TEF_MSGOBJ* tefObj)
01368 {
01369     int8_t spiTransferError = 0;
01370     uint16_t a = 0;
01371     uint32_t fifoReg[3];
01372     uint8_t n = 0;
01373 
01374     // Get FIFO registers
01375     a = cREGADDR_CiTEFCON;
01376 
01377     spiTransferError = DRV_CANFDSPI_ReadWordArray(index, a, fifoReg, 3);
01378     if (spiTransferError) {
01379         return -1;
01380     }
01381 
01382     // Get control
01383     REG_CiTEFCON ciTefCon;
01384     ciTefCon.word = fifoReg[0];
01385 
01386     // Get status
01387     REG_CiTEFSTA ciTefSta;
01388     ciTefSta.word = fifoReg[1];
01389 
01390     // Get address
01391     REG_CiFIFOUA ciTefUa;
01392     ciTefUa.word = fifoReg[2];
01393 #ifdef USERADDRESS_TIMES_FOUR
01394     a = 4 * ciTefUa.bF.UserAddress;
01395 #else
01396     a = ciTefUa.bF.UserAddress;
01397 #endif
01398     a += cRAMADDR_START;
01399 
01400     // Number of bytes to read
01401     n = 8; // 8 header bytes
01402 
01403     if (ciTefCon.bF.TimeStampEnable) {
01404         n += 4; // Add 4 time stamp bytes
01405     }
01406 
01407     // Read rxObj using one access
01408     uint8_t ba[12];
01409 
01410     spiTransferError = DRV_CANFDSPI_ReadByteArray(index, a, ba, n);
01411     if (spiTransferError) {
01412         return -2;
01413     }
01414 
01415     // Assign message header
01416     REG_t myReg;
01417 
01418     myReg.byte[0] = ba[0];
01419     myReg.byte[1] = ba[1];
01420     myReg.byte[2] = ba[2];
01421     myReg.byte[3] = ba[3];
01422     tefObj->word[0] = myReg.word;
01423 
01424     myReg.byte[0] = ba[4];
01425     myReg.byte[1] = ba[5];
01426     myReg.byte[2] = ba[6];
01427     myReg.byte[3] = ba[7];
01428     tefObj->word[1] = myReg.word;
01429 
01430     if (ciTefCon.bF.TimeStampEnable) {
01431         myReg.byte[0] = ba[8];
01432         myReg.byte[1] = ba[9];
01433         myReg.byte[2] = ba[10];
01434         myReg.byte[3] = ba[11];
01435         tefObj->word[2] = myReg.word;
01436     } else {
01437         tefObj->word[2] = 0;
01438     }
01439 
01440     // Set UINC
01441     spiTransferError = DRV_CANFDSPI_TefUpdate(index);
01442     if (spiTransferError) {
01443         return -3;
01444     }
01445 
01446     return spiTransferError;
01447 }
01448 
01449 int8_t DRV_CANFDSPI_TefReset(CANFDSPI_MODULE_ID index)
01450 {
01451     int8_t spiTransferError = 0;
01452     uint16_t a = 0;
01453 
01454     // Set FRESET
01455     a = cREGADDR_CiTEFCON + 1;
01456     REG_CiTEFCON ciTefCon;
01457     ciTefCon.word = 0;
01458     ciTefCon.bF.FRESET = 1;
01459 
01460     // Write byte
01461     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciTefCon.byte[1]);
01462 
01463     return spiTransferError;
01464 }
01465 
01466 int8_t DRV_CANFDSPI_TefUpdate(CANFDSPI_MODULE_ID index)
01467 {
01468     int8_t spiTransferError = 0;
01469     uint16_t a = 0;
01470 
01471     // Set UINC
01472     a = cREGADDR_CiTEFCON + 1;
01473     REG_CiTEFCON ciTefCon;
01474     ciTefCon.word = 0;
01475     ciTefCon.bF.UINC = 1;
01476 
01477     // Write byte
01478     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciTefCon.byte[1]);
01479 
01480     return spiTransferError;
01481 }
01482 
01483 int8_t DRV_CANFDSPI_TefConfigure(CANFDSPI_MODULE_ID index, CAN_TEF_CONFIG* config)
01484 {
01485     int8_t spiTransferError = 0;
01486 
01487     // Setup FIFO
01488     REG_CiTEFCON ciTefCon;
01489     ciTefCon.word = canControlResetValues[cREGADDR_CiTEFCON / 4];
01490 
01491     ciTefCon.bF.FifoSize = config->FifoSize;
01492     ciTefCon.bF.TimeStampEnable = config->TimeStampEnable;
01493 
01494     spiTransferError = DRV_CANFDSPI_WriteWord(index, cREGADDR_CiTEFCON, ciTefCon.word);
01495 
01496     return spiTransferError;
01497 }
01498 
01499 int8_t DRV_CANFDSPI_TefConfigureObjectReset(CAN_TEF_CONFIG* config)
01500 {
01501     REG_CiTEFCON ciTefCon;
01502     ciTefCon.word = canControlResetValues[cREGADDR_CiFIFOCON / 4];
01503 
01504     config->FifoSize = ciTefCon.bF.FifoSize;
01505     config->TimeStampEnable = ciTefCon.bF.TimeStampEnable;
01506 
01507     return 0;
01508 }
01509 
01510 
01511 // *****************************************************************************
01512 // *****************************************************************************
01513 // Section: Module Events
01514 
01515 int8_t DRV_CANFDSPI_ModuleEventGet(CANFDSPI_MODULE_ID index,
01516         CAN_MODULE_EVENT* flags)
01517 {
01518     int8_t spiTransferError = 0;
01519 
01520     // Read Interrupt flags
01521     REG_CiINTFLAG intFlags;
01522     intFlags.word = 0;
01523 
01524     spiTransferError = DRV_CANFDSPI_ReadHalfWord(index, cREGADDR_CiINTFLAG, &intFlags.word);
01525     if (spiTransferError) {
01526         return -1;
01527     }
01528 
01529     // Update data
01530     *flags = (CAN_MODULE_EVENT) (intFlags.word & CAN_ALL_EVENTS);
01531 
01532     return spiTransferError;
01533 }
01534 
01535 int8_t DRV_CANFDSPI_ModuleEventEnable(CANFDSPI_MODULE_ID index,
01536         CAN_MODULE_EVENT flags)
01537 {
01538     int8_t spiTransferError = 0;
01539     uint16_t a = 0;
01540 
01541     // Read Interrupt Enables
01542     a = cREGADDR_CiINTENABLE;
01543     REG_CiINTENABLE intEnables;
01544     intEnables.word = 0;
01545 
01546     spiTransferError = DRV_CANFDSPI_ReadHalfWord(index, a, &intEnables.word);
01547     if (spiTransferError) {
01548         return -1;
01549     }
01550 
01551     // Modify
01552     intEnables.word |= (flags & CAN_ALL_EVENTS);
01553 
01554     // Write
01555     spiTransferError = DRV_CANFDSPI_WriteHalfWord(index, a, intEnables.word);
01556     if (spiTransferError) {
01557         return -2;
01558     }
01559 
01560     return spiTransferError;
01561 }
01562 
01563 int8_t DRV_CANFDSPI_ModuleEventDisable(CANFDSPI_MODULE_ID index,
01564         CAN_MODULE_EVENT flags)
01565 {
01566     int8_t spiTransferError = 0;
01567     uint16_t a = 0;
01568 
01569     // Read Interrupt Enables
01570     a = cREGADDR_CiINTENABLE;
01571     REG_CiINTENABLE intEnables;
01572     intEnables.word = 0;
01573 
01574     spiTransferError = DRV_CANFDSPI_ReadHalfWord(index, a, &intEnables.word);
01575     if (spiTransferError) {
01576         return -1;
01577     }
01578 
01579     // Modify
01580     intEnables.word &= ~(flags & CAN_ALL_EVENTS);
01581 
01582     // Write
01583     spiTransferError = DRV_CANFDSPI_WriteHalfWord(index, a, intEnables.word);
01584     if (spiTransferError) {
01585         return -2;
01586     }
01587 
01588     return spiTransferError;
01589 }
01590 
01591 int8_t DRV_CANFDSPI_ModuleEventClear(CANFDSPI_MODULE_ID index,
01592         CAN_MODULE_EVENT flags)
01593 {
01594     int8_t spiTransferError = 0;
01595     uint16_t a = 0;
01596 
01597     // Read Interrupt flags
01598     a = cREGADDR_CiINTFLAG;
01599     REG_CiINTFLAG intFlags;
01600     intFlags.word = 0;
01601 
01602     // Write 1 to all flags except the ones that we want to clear
01603     // Writing a 1 will not set the flag
01604     // Only writing a 0 will clear it
01605     // The flags are HS/C
01606     intFlags.word = CAN_ALL_EVENTS;
01607     intFlags.word &= ~flags;
01608 
01609     // Write
01610     spiTransferError = DRV_CANFDSPI_WriteHalfWord(index, a, intFlags.word);
01611     if (spiTransferError) {
01612         return -2;
01613     }
01614 
01615     return spiTransferError;
01616 }
01617 
01618 int8_t DRV_CANFDSPI_ModuleEventRxCodeGet(CANFDSPI_MODULE_ID index,
01619         CAN_RXCODE* rxCode)
01620 {
01621     int8_t spiTransferError = 0;
01622     uint16_t a = 0;
01623     uint8_t rxCodeByte = 0;
01624 
01625     // Read
01626     a = cREGADDR_CiVEC + 3;
01627 
01628     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &rxCodeByte);
01629     if (spiTransferError) {
01630         return -1;
01631     }
01632 
01633     // Decode data
01634     // 0x40 = "no interrupt" (CAN_FIFO_CIVEC_NOINTERRUPT)
01635     if ((rxCodeByte < CAN_RXCODE_TOTAL_CHANNELS) || (rxCodeByte == CAN_RXCODE_NO_INT)) {
01636         *rxCode = (CAN_RXCODE) rxCodeByte;
01637     } else {
01638         *rxCode = CAN_RXCODE_RESERVED; // shouldn't get here
01639     }
01640 
01641     return spiTransferError;
01642 }
01643 
01644 int8_t DRV_CANFDSPI_ModuleEventTxCodeGet(CANFDSPI_MODULE_ID index,
01645         CAN_TXCODE* txCode)
01646 {
01647     int8_t spiTransferError = 0;
01648     uint16_t a = 0;
01649     uint8_t txCodeByte = 0;
01650 
01651     // Read
01652     a = cREGADDR_CiVEC + 2;
01653 
01654     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &txCodeByte);
01655     if (spiTransferError) {
01656         return -1;
01657     }
01658 
01659     // Decode data
01660     // 0x40 = "no interrupt" (CAN_FIFO_CIVEC_NOINTERRUPT)
01661     if ((txCodeByte < CAN_TXCODE_TOTAL_CHANNELS) || (txCodeByte == CAN_TXCODE_NO_INT)) {
01662         *txCode = (CAN_TXCODE) txCodeByte;
01663     } else {
01664         *txCode = CAN_TXCODE_RESERVED; // shouldn't get here
01665     }
01666 
01667     return spiTransferError;
01668 }
01669 
01670 int8_t DRV_CANFDSPI_ModuleEventFilterHitGet(CANFDSPI_MODULE_ID index,
01671         CAN_FILTER* filterHit)
01672 {
01673     int8_t spiTransferError = 0;
01674     uint16_t a = 0;
01675     uint8_t filterHitByte = 0;
01676 
01677     // Read
01678     a = cREGADDR_CiVEC + 1;
01679 
01680     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &filterHitByte);
01681     if (spiTransferError) {
01682         return -1;
01683     }
01684 
01685     // Update data
01686     *filterHit = (CAN_FILTER) filterHitByte;
01687 
01688     return spiTransferError;
01689 }
01690 
01691 int8_t DRV_CANFDSPI_ModuleEventIcodeGet(CANFDSPI_MODULE_ID index,
01692         CAN_ICODE* icode)
01693 {
01694     int8_t spiTransferError = 0;
01695     uint16_t a = 0;
01696     uint8_t icodeByte = 0;
01697 
01698     // Read
01699     a = cREGADDR_CiVEC;
01700 
01701     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &icodeByte);
01702     if (spiTransferError) {
01703         return -1;
01704     }
01705 
01706     // Decode
01707     if ((icodeByte < CAN_ICODE_RESERVED) && ((icodeByte < CAN_ICODE_TOTAL_CHANNELS) || (icodeByte >= CAN_ICODE_NO_INT))) {
01708         *icode = (CAN_ICODE) icodeByte;
01709     } else {
01710         *icode = CAN_ICODE_RESERVED; // shouldn't get here
01711     }
01712 
01713     return spiTransferError;
01714 }
01715 
01716 // *****************************************************************************
01717 // *****************************************************************************
01718 // Section: Transmit FIFO Events
01719 
01720 int8_t DRV_CANFDSPI_TransmitChannelEventGet(CANFDSPI_MODULE_ID index,
01721         CAN_FIFO_CHANNEL channel, CAN_TX_FIFO_EVENT* flags)
01722 {
01723     int8_t spiTransferError = 0;
01724     uint16_t a = 0;
01725 
01726     // Read Interrupt flags
01727     REG_CiFIFOSTA ciFifoSta;
01728     ciFifoSta.word = 0;
01729     a = cREGADDR_CiFIFOSTA + (channel * CiFIFO_OFFSET);
01730 
01731     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciFifoSta.byte[0]);
01732     if (spiTransferError) {
01733         return -1;
01734     }
01735 
01736     // Update data
01737     *flags = (CAN_TX_FIFO_EVENT) (ciFifoSta.byte[0] & CAN_TX_FIFO_ALL_EVENTS);
01738 
01739     return spiTransferError;
01740 }
01741 
01742 int8_t DRV_CANFDSPI_TransmitEventGet(CANFDSPI_MODULE_ID index, uint32_t* txif)
01743 {
01744     int8_t spiTransferError = 0;
01745 
01746     spiTransferError = DRV_CANFDSPI_ReadWord(index, cREGADDR_CiTXIF, txif);
01747 
01748     return spiTransferError;
01749 }
01750 
01751 int8_t DRV_CANFDSPI_TransmitEventAttemptGet(CANFDSPI_MODULE_ID index,
01752         uint32_t* txatif)
01753 {
01754     int8_t spiTransferError = 0;
01755 
01756     spiTransferError = DRV_CANFDSPI_ReadWord(index, cREGADDR_CiTXATIF, txatif);
01757 
01758     return spiTransferError;
01759 }
01760 
01761 int8_t DRV_CANFDSPI_TransmitChannelIndexGet(CANFDSPI_MODULE_ID index,
01762         CAN_FIFO_CHANNEL channel, uint8_t* idx)
01763 {
01764     int8_t spiTransferError = 0;
01765     uint16_t a = 0;
01766 
01767     // Read index
01768     REG_CiFIFOSTA ciFifoSta;
01769     ciFifoSta.word = 0;
01770     a = cREGADDR_CiFIFOSTA + (channel * CiFIFO_OFFSET);
01771 
01772     spiTransferError = DRV_CANFDSPI_ReadWord(index, a, &ciFifoSta.word);
01773     if (spiTransferError) {
01774         return -1;
01775     }
01776 
01777     // Update data
01778     *idx = ciFifoSta.txBF.FifoIndex;
01779 
01780     return spiTransferError;
01781 }
01782 
01783 int8_t DRV_CANFDSPI_TransmitChannelEventEnable(CANFDSPI_MODULE_ID index,
01784         CAN_FIFO_CHANNEL channel, CAN_TX_FIFO_EVENT flags)
01785 {
01786     int8_t spiTransferError = 0;
01787     uint16_t a = 0;
01788 
01789     // Read Interrupt Enables
01790     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET);
01791     REG_CiFIFOCON ciFifoCon;
01792     ciFifoCon.word = 0;
01793 
01794     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciFifoCon.byte[0]);
01795     if (spiTransferError) {
01796         return -1;
01797     }
01798 
01799     // Modify
01800     ciFifoCon.byte[0] |= (flags & CAN_TX_FIFO_ALL_EVENTS);
01801 
01802     // Write
01803     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciFifoCon.byte[0]);
01804     if (spiTransferError) {
01805         return -2;
01806     }
01807 
01808     return spiTransferError;
01809 }
01810 
01811 int8_t DRV_CANFDSPI_TransmitChannelEventDisable(CANFDSPI_MODULE_ID index,
01812         CAN_FIFO_CHANNEL channel, CAN_TX_FIFO_EVENT flags)
01813 {
01814     int8_t spiTransferError = 0;
01815     uint16_t a = 0;
01816 
01817     // Read Interrupt Enables
01818     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET);
01819     REG_CiFIFOCON ciFifoCon;
01820     ciFifoCon.word = 0;
01821 
01822     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciFifoCon.byte[0]);
01823     if (spiTransferError) {
01824         return -1;
01825     }
01826 
01827     // Modify
01828     ciFifoCon.byte[0] &= ~(flags & CAN_TX_FIFO_ALL_EVENTS);
01829 
01830     // Write
01831     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciFifoCon.byte[0]);
01832     if (spiTransferError) {
01833         return -2;
01834     }
01835 
01836     return spiTransferError;
01837 }
01838 
01839 int8_t DRV_CANFDSPI_TransmitChannelEventAttemptClear(CANFDSPI_MODULE_ID index,
01840         CAN_FIFO_CHANNEL channel)
01841 {
01842     int8_t spiTransferError = 0;
01843     uint16_t a = 0;
01844 
01845     // Read Interrupt Enables
01846     a = cREGADDR_CiFIFOSTA + (channel * CiFIFO_OFFSET);
01847     REG_CiFIFOSTA ciFifoSta;
01848     ciFifoSta.word = 0;
01849 
01850     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciFifoSta.byte[0]);
01851     if (spiTransferError) {
01852         return -1;
01853     }
01854 
01855     // Modify
01856     ciFifoSta.byte[0] &= ~CAN_TX_FIFO_ATTEMPTS_EXHAUSTED_EVENT;
01857 
01858     // Write
01859     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciFifoSta.byte[0]);
01860     if (spiTransferError) {
01861         return -2;
01862     }
01863 
01864     return spiTransferError;
01865 }
01866 
01867 
01868 // *****************************************************************************
01869 // *****************************************************************************
01870 // Section: Receive FIFO Events
01871 
01872 int8_t DRV_CANFDSPI_ReceiveChannelEventGet(CANFDSPI_MODULE_ID index,
01873         CAN_FIFO_CHANNEL channel, CAN_RX_FIFO_EVENT* flags)
01874 {
01875     int8_t spiTransferError = 0;
01876     uint16_t a = 0;
01877 
01878 #ifdef CAN_TXQUEUE_IMPLEMENTED
01879     if (channel == CAN_TXQUEUE_CH0) return -100;
01880 #endif
01881 
01882     // Read Interrupt flags
01883     REG_CiFIFOSTA ciFifoSta;
01884     ciFifoSta.word = 0;
01885     a = cREGADDR_CiFIFOSTA + (channel * CiFIFO_OFFSET);
01886 
01887     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciFifoSta.byte[0]);
01888     if (spiTransferError) {
01889         return -1;
01890     }
01891 
01892     // Update data
01893     *flags = (CAN_RX_FIFO_EVENT) (ciFifoSta.byte[0] & CAN_RX_FIFO_ALL_EVENTS);
01894 
01895     return spiTransferError;
01896 }
01897 
01898 int8_t DRV_CANFDSPI_ReceiveEventGet(CANFDSPI_MODULE_ID index, uint32_t* rxif)
01899 {
01900     int8_t spiTransferError = 0;
01901 
01902     spiTransferError = DRV_CANFDSPI_ReadWord(index, cREGADDR_CiRXIF, rxif);
01903 
01904     return spiTransferError;
01905 }
01906 
01907 int8_t DRV_CANFDSPI_ReceiveEventOverflowGet(CANFDSPI_MODULE_ID index,
01908         uint32_t* rxovif)
01909 {
01910     int8_t spiTransferError = 0;
01911 
01912     spiTransferError = DRV_CANFDSPI_ReadWord(index, cREGADDR_CiRXOVIF, rxovif);
01913 
01914     return spiTransferError;
01915 }
01916 
01917 int8_t DRV_CANFDSPI_ReceiveChannelIndexGet(CANFDSPI_MODULE_ID index,
01918         CAN_FIFO_CHANNEL channel, uint8_t* idx)
01919 {
01920     return DRV_CANFDSPI_TransmitChannelIndexGet(index, channel, idx);
01921 }
01922 
01923 int8_t DRV_CANFDSPI_ReceiveChannelEventEnable(CANFDSPI_MODULE_ID index,
01924         CAN_FIFO_CHANNEL channel, CAN_RX_FIFO_EVENT flags)
01925 {
01926     int8_t spiTransferError = 0;
01927     uint16_t a = 0;
01928 
01929 #ifdef CAN_TXQUEUE_IMPLEMENTED
01930     if (channel == CAN_TXQUEUE_CH0) return -100;
01931 #endif
01932 
01933     // Read Interrupt Enables
01934     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET);
01935     REG_CiFIFOCON ciFifoCon;
01936     ciFifoCon.word = 0;
01937 
01938     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciFifoCon.byte[0]);
01939     if (spiTransferError) {
01940         return -1;
01941     }
01942 
01943     // Modify
01944     ciFifoCon.byte[0] |= (flags & CAN_RX_FIFO_ALL_EVENTS);
01945 
01946     // Write
01947     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciFifoCon.byte[0]);
01948     if (spiTransferError) {
01949         return -2;
01950     }
01951 
01952     return spiTransferError;
01953 }
01954 
01955 int8_t DRV_CANFDSPI_ReceiveChannelEventDisable(CANFDSPI_MODULE_ID index,
01956         CAN_FIFO_CHANNEL channel, CAN_RX_FIFO_EVENT flags)
01957 {
01958     int8_t spiTransferError = 0;
01959     uint16_t a = 0;
01960 
01961 #ifdef CAN_TXQUEUE_IMPLEMENTED
01962     if (channel == CAN_TXQUEUE_CH0) return -100;
01963 #endif
01964 
01965     // Read Interrupt Enables
01966     a = cREGADDR_CiFIFOCON + (channel * CiFIFO_OFFSET);
01967     REG_CiFIFOCON ciFifoCon;
01968     ciFifoCon.word = 0;
01969 
01970     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciFifoCon.byte[0]);
01971     if (spiTransferError) {
01972         return -1;
01973     }
01974 
01975     // Modify
01976     ciFifoCon.byte[0] &= ~(flags & CAN_RX_FIFO_ALL_EVENTS);
01977 
01978     // Write
01979     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciFifoCon.byte[0]);
01980     if (spiTransferError) {
01981         return -2;
01982     }
01983 
01984     return spiTransferError;
01985 }
01986 
01987 int8_t DRV_CANFDSPI_ReceiveChannelEventOverflowClear(CANFDSPI_MODULE_ID index,
01988         CAN_FIFO_CHANNEL channel)
01989 {
01990     int8_t spiTransferError = 0;
01991     uint16_t a = 0;
01992 
01993 #ifdef CAN_TXQUEUE_IMPLEMENTED
01994     if (channel == CAN_TXQUEUE_CH0) return -100;
01995 #endif
01996 
01997     // Read Interrupt Flags
01998     REG_CiFIFOSTA ciFifoSta;
01999     ciFifoSta.word = 0;
02000     a = cREGADDR_CiFIFOSTA + (channel * CiFIFO_OFFSET);
02001 
02002     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciFifoSta.byte[0]);
02003     if (spiTransferError) {
02004         return -1;
02005     }
02006 
02007     // Modify
02008     ciFifoSta.byte[0] &= ~(CAN_RX_FIFO_OVERFLOW_EVENT);
02009 
02010     // Write
02011     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciFifoSta.byte[0]);
02012     if (spiTransferError) {
02013         return -2;
02014     }
02015 
02016     return spiTransferError;
02017 }
02018 
02019 
02020 // *****************************************************************************
02021 // *****************************************************************************
02022 // Section: Transmit Event FIFO Events
02023 
02024 int8_t DRV_CANFDSPI_TefEventGet(CANFDSPI_MODULE_ID index,
02025         CAN_TEF_FIFO_EVENT* flags)
02026 {
02027     int8_t spiTransferError = 0;
02028     uint16_t a = 0;
02029 
02030     // Read Interrupt flags
02031     REG_CiTEFSTA ciTefSta;
02032     ciTefSta.word = 0;
02033     a = cREGADDR_CiTEFSTA;
02034 
02035     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciTefSta.byte[0]);
02036     if (spiTransferError) {
02037         return -1;
02038     }
02039 
02040     // Update data
02041     *flags = (CAN_TEF_FIFO_EVENT) (ciTefSta.byte[0] & CAN_TEF_FIFO_ALL_EVENTS);
02042 
02043     return spiTransferError;
02044 }
02045 
02046 int8_t DRV_CANFDSPI_TefEventEnable(CANFDSPI_MODULE_ID index,
02047         CAN_TEF_FIFO_EVENT flags)
02048 {
02049     int8_t spiTransferError = 0;
02050     uint16_t a = 0;
02051 
02052     // Read Interrupt Enables
02053     a = cREGADDR_CiTEFCON;
02054     REG_CiTEFCON ciTefCon;
02055     ciTefCon.word = 0;
02056 
02057     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciTefCon.byte[0]);
02058     if (spiTransferError) {
02059         return -1;
02060     }
02061 
02062     // Modify
02063     ciTefCon.byte[0] |= (flags & CAN_TEF_FIFO_ALL_EVENTS);
02064 
02065     // Write
02066     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciTefCon.byte[0]);
02067     if (spiTransferError) {
02068         return -2;
02069     }
02070 
02071     return spiTransferError;
02072 }
02073 
02074 int8_t DRV_CANFDSPI_TefEventDisable(CANFDSPI_MODULE_ID index,
02075         CAN_TEF_FIFO_EVENT flags)
02076 {
02077     int8_t spiTransferError = 0;
02078     uint16_t a = 0;
02079 
02080     // Read Interrupt Enables
02081     a = cREGADDR_CiTEFCON;
02082     REG_CiTEFCON ciTefCon;
02083     ciTefCon.word = 0;
02084 
02085     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciTefCon.byte[0]);
02086     if (spiTransferError) {
02087         return -1;
02088     }
02089 
02090     // Modify
02091     ciTefCon.byte[0] &= ~(flags & CAN_TEF_FIFO_ALL_EVENTS);
02092 
02093     // Write
02094     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciTefCon.byte[0]);
02095     if (spiTransferError) {
02096         return -2;
02097     }
02098 
02099     return spiTransferError;
02100 }
02101 
02102 int8_t DRV_CANFDSPI_TefEventOverflowClear(CANFDSPI_MODULE_ID index)
02103 {
02104     int8_t spiTransferError = 0;
02105     uint16_t a = 0;
02106 
02107     // Read Interrupt Flags
02108     REG_CiTEFSTA ciTefSta;
02109     ciTefSta.word = 0;
02110     a = cREGADDR_CiTEFSTA;
02111 
02112     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &ciTefSta.byte[0]);
02113     if (spiTransferError) {
02114         return -1;
02115     }
02116 
02117     // Modify
02118     ciTefSta.byte[0] &= ~(CAN_TEF_FIFO_OVERFLOW_EVENT);
02119 
02120     // Write
02121     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, ciTefSta.byte[0]);
02122     if (spiTransferError) {
02123         return -2;
02124     }
02125 
02126     return spiTransferError;
02127 }
02128 
02129 
02130 // *****************************************************************************
02131 // *****************************************************************************
02132 // Section: Error Handling
02133 
02134 int8_t DRV_CANFDSPI_ErrorCountTransmitGet(CANFDSPI_MODULE_ID index,
02135         uint8_t* tec)
02136 {
02137     int8_t spiTransferError = 0;
02138     uint16_t a = 0;
02139 
02140     // Read Error count
02141     a = cREGADDR_CiTREC + 1;
02142 
02143     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, tec);
02144 
02145     return spiTransferError;
02146 }
02147 
02148 int8_t DRV_CANFDSPI_ErrorCountReceiveGet(CANFDSPI_MODULE_ID index,
02149         uint8_t* rec)
02150 {
02151     int8_t spiTransferError = 0;
02152     uint16_t a = 0;
02153 
02154     // Read Error count
02155     a = cREGADDR_CiTREC;
02156 
02157     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, rec);
02158 
02159     return spiTransferError;
02160 }
02161 
02162 int8_t DRV_CANFDSPI_ErrorStateGet(CANFDSPI_MODULE_ID index,
02163         CAN_ERROR_STATE* flags)
02164 {
02165     int8_t spiTransferError = 0;
02166     uint16_t a = 0;
02167 
02168     // Read Error state
02169     a = cREGADDR_CiTREC + 2;
02170     uint8_t f = 0;
02171 
02172     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &f);
02173     if (spiTransferError) {
02174         return -1;
02175     }
02176 
02177     // Update data
02178     *flags = (CAN_ERROR_STATE) (f & CAN_ERROR_ALL);
02179 
02180     return spiTransferError;
02181 }
02182 
02183 int8_t DRV_CANFDSPI_ErrorCountStateGet(CANFDSPI_MODULE_ID index,
02184         uint8_t* tec, uint8_t* rec, CAN_ERROR_STATE* flags)
02185 {
02186     int8_t spiTransferError = 0;
02187     uint16_t a = 0;
02188 
02189     // Read Error
02190     a = cREGADDR_CiTREC;
02191     REG_CiTREC ciTrec;
02192     ciTrec.word = 0;
02193 
02194     spiTransferError = DRV_CANFDSPI_ReadWord(index, a, &ciTrec.word);
02195     if (spiTransferError) {
02196         return -1;
02197     }
02198 
02199     // Update data
02200     *tec = ciTrec.byte[1];
02201     *rec = ciTrec.byte[0];
02202     *flags = (CAN_ERROR_STATE) (ciTrec.byte[2] & CAN_ERROR_ALL);
02203 
02204     return spiTransferError;
02205 }
02206 
02207 int8_t DRV_CANFDSPI_BusDiagnosticsGet(CANFDSPI_MODULE_ID index,
02208         CAN_BUS_DIAGNOSTIC* bd)
02209 {
02210     int8_t spiTransferError = 0;
02211     uint16_t a = 0;
02212 
02213     // Read diagnostic registers all in one shot
02214     a = cREGADDR_CiBDIAG0;
02215     uint32_t w[2];
02216 
02217     spiTransferError = DRV_CANFDSPI_ReadWordArray(index, a, w, 2);
02218     if (spiTransferError) {
02219         return -1;
02220     }
02221 
02222     // Update data
02223     CAN_BUS_DIAGNOSTIC b;
02224     b.word[0] = w[0];
02225     b.word[1] = w[1] & 0x0000ffff;
02226     b.word[2] = (w[1] >> 16) & 0x0000ffff;
02227     *bd = b;
02228 
02229     return spiTransferError;
02230 }
02231 
02232 int8_t DRV_CANFDSPI_BusDiagnosticsClear(CANFDSPI_MODULE_ID index)
02233 {
02234     int8_t spiTransferError = 0;
02235     uint8_t a = 0;
02236 
02237     // Clear diagnostic registers all in one shot
02238     a = cREGADDR_CiBDIAG0;
02239     uint32_t w[2];
02240     w[0] = 0;
02241     w[1] = 0;
02242 
02243     spiTransferError = DRV_CANFDSPI_WriteWordArray(index, a, w, 2);
02244 
02245     return spiTransferError;
02246 }
02247 
02248 
02249 // *****************************************************************************
02250 // *****************************************************************************
02251 // Section: ECC
02252 
02253 int8_t DRV_CANFDSPI_EccEnable(CANFDSPI_MODULE_ID index)
02254 {
02255     int8_t spiTransferError = 0;
02256     uint8_t d = 0;
02257 
02258     // Read
02259     spiTransferError = DRV_CANFDSPI_ReadByte(index, cREGADDR_ECCCON, &d);
02260     if (spiTransferError) {
02261         return -1;
02262     }
02263 
02264     // Modify
02265     d |= 0x01;
02266 
02267     // Write
02268     spiTransferError = DRV_CANFDSPI_WriteByte(index, cREGADDR_ECCCON, d);
02269     if (spiTransferError) {
02270         return -2;
02271     }
02272 
02273     return 0;
02274 }
02275 
02276 int8_t DRV_CANFDSPI_EccDisable(CANFDSPI_MODULE_ID index)
02277 {
02278     int8_t spiTransferError = 0;
02279     uint8_t d = 0;
02280 
02281     // Read
02282     spiTransferError = DRV_CANFDSPI_ReadByte(index, cREGADDR_ECCCON, &d);
02283     if (spiTransferError) {
02284         return -1;
02285     }
02286 
02287     // Modify
02288     d &= ~0x01;
02289 
02290     // Write
02291     spiTransferError = DRV_CANFDSPI_WriteByte(index, cREGADDR_ECCCON, d);
02292     if (spiTransferError) {
02293         return -2;
02294     }
02295 
02296     return 0;
02297 }
02298 
02299 int8_t DRV_CANFDSPI_EccEventGet(CANFDSPI_MODULE_ID index,
02300         CAN_ECC_EVENT* flags)
02301 {
02302     int8_t spiTransferError = 0;
02303     uint16_t a = 0;
02304 
02305     // Read Interrupt flags
02306     uint8_t eccStatus = 0;
02307     a = cREGADDR_ECCSTA;
02308 
02309     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &eccStatus);
02310     if (spiTransferError) {
02311         return -1;
02312     }
02313 
02314     // Update data
02315     *flags = (CAN_ECC_EVENT) (eccStatus & CAN_ECC_ALL_EVENTS);
02316 
02317     return spiTransferError;
02318 }
02319 
02320 int8_t DRV_CANFDSPI_EccParitySet(CANFDSPI_MODULE_ID index,
02321         uint8_t parity)
02322 {
02323     int8_t spiTransferError = 0;
02324 
02325     // Write
02326     spiTransferError = DRV_CANFDSPI_WriteByte(index, cREGADDR_ECCCON + 1, parity);
02327 
02328     return spiTransferError;
02329 }
02330 
02331 int8_t DRV_CANFDSPI_EccParityGet(CANFDSPI_MODULE_ID index,
02332         uint8_t* parity)
02333 {
02334     int8_t spiTransferError = 0;
02335 
02336     // Read
02337     spiTransferError = DRV_CANFDSPI_ReadByte(index, cREGADDR_ECCCON + 1, parity);
02338 
02339     return spiTransferError;
02340 }
02341 
02342 int8_t DRV_CANFDSPI_EccErrorAddressGet(CANFDSPI_MODULE_ID index,
02343         uint16_t* a)
02344 {
02345     int8_t spiTransferError = 0;
02346     REG_ECCSTA reg;
02347 
02348     // Read
02349     spiTransferError = DRV_CANFDSPI_ReadWord(index, cREGADDR_ECCSTA, &reg.word);
02350     if (spiTransferError) {
02351         return -1;
02352     }
02353 
02354     // Update data
02355     *a = reg.bF.ErrorAddress;
02356 
02357     return spiTransferError;
02358 }
02359 
02360 int8_t DRV_CANFDSPI_EccEventEnable(CANFDSPI_MODULE_ID index,
02361         CAN_ECC_EVENT flags)
02362 {
02363     int8_t spiTransferError = 0;
02364     uint16_t a = 0;
02365 
02366     // Read
02367     a = cREGADDR_ECCCON;
02368     uint8_t eccInterrupts = 0;
02369 
02370     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &eccInterrupts);
02371     if (spiTransferError) {
02372         return -1;
02373     }
02374 
02375     // Modify
02376     eccInterrupts |= (flags & CAN_ECC_ALL_EVENTS);
02377 
02378     // Write
02379     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, eccInterrupts);
02380     if (spiTransferError) {
02381         return -2;
02382     }
02383 
02384     return spiTransferError;
02385 }
02386 
02387 int8_t DRV_CANFDSPI_EccEventDisable(CANFDSPI_MODULE_ID index,
02388         CAN_ECC_EVENT flags)
02389 {
02390     int8_t spiTransferError = 0;
02391     uint16_t a = 0;
02392 
02393     // Read
02394     a = cREGADDR_ECCCON;
02395     uint8_t eccInterrupts = 0;
02396 
02397     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &eccInterrupts);
02398     if (spiTransferError) {
02399         return -1;
02400     }
02401 
02402     // Modify
02403     eccInterrupts &= ~(flags & CAN_ECC_ALL_EVENTS);
02404 
02405     // Write
02406     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, eccInterrupts);
02407     if (spiTransferError) {
02408         return -2;
02409     }
02410 
02411     return spiTransferError;
02412 }
02413 
02414 int8_t DRV_CANFDSPI_EccEventClear(CANFDSPI_MODULE_ID index,
02415         CAN_ECC_EVENT flags)
02416 {
02417     int8_t spiTransferError = 0;
02418     uint16_t a = 0;
02419 
02420     // Read
02421     a = cREGADDR_ECCSTA;
02422     uint8_t eccStat = 0;
02423 
02424     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &eccStat);
02425     if (spiTransferError) {
02426         return -1;
02427     }
02428 
02429     // Modify
02430     eccStat &= ~(flags & CAN_ECC_ALL_EVENTS);
02431 
02432     // Write
02433     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, eccStat);
02434     if (spiTransferError) {
02435         return -2;
02436     }
02437 
02438     return spiTransferError;
02439 }
02440 
02441 
02442 // *****************************************************************************
02443 // *****************************************************************************
02444 // Section: CRC
02445 
02446 int8_t DRV_CANFDSPI_CrcEventEnable(CANFDSPI_MODULE_ID index,
02447         CAN_CRC_EVENT flags)
02448 {
02449     int8_t spiTransferError = 0;
02450     uint16_t a = 0;
02451 
02452     // Read interrupt control bits of CRC Register
02453     a = cREGADDR_CRC + 3;
02454     uint8_t crc;
02455 
02456     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &crc);
02457     if (spiTransferError) {
02458         return -1;
02459     }
02460 
02461     // Modify
02462     crc |= (flags & CAN_CRC_ALL_EVENTS);
02463 
02464     // Write
02465     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, crc);
02466     if (spiTransferError) {
02467         return -2;
02468     }
02469 
02470     return spiTransferError;
02471 }
02472 
02473 int8_t DRV_CANFDSPI_CrcEventDisable(CANFDSPI_MODULE_ID index,
02474         CAN_CRC_EVENT flags)
02475 {
02476     int8_t spiTransferError = 0;
02477     uint16_t a = 0;
02478 
02479     // Read interrupt control bits of CRC Register
02480     a = cREGADDR_CRC + 3;
02481     uint8_t crc;
02482 
02483     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &crc);
02484     if (spiTransferError) {
02485         return -1;
02486     }
02487 
02488     // Modify
02489     crc &= ~(flags & CAN_CRC_ALL_EVENTS);
02490 
02491     // Write
02492     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, crc);
02493     if (spiTransferError) {
02494         return -2;
02495     }
02496 
02497     return spiTransferError;
02498 }
02499 
02500 int8_t DRV_CANFDSPI_CrcEventClear(CANFDSPI_MODULE_ID index,
02501         CAN_CRC_EVENT flags)
02502 {
02503     int8_t spiTransferError = 0;
02504     uint16_t a = 0;
02505 
02506     // Read interrupt flags of CRC Register
02507     a = cREGADDR_CRC + 2;
02508     uint8_t crc;
02509 
02510     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &crc);
02511     if (spiTransferError) {
02512         return -1;
02513     }
02514 
02515     // Modify
02516     crc &= ~(flags & CAN_CRC_ALL_EVENTS);
02517 
02518     // Write
02519     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, crc);
02520     if (spiTransferError) {
02521         return -2;
02522     }
02523 
02524     return spiTransferError;
02525 }
02526 
02527 int8_t DRV_CANFDSPI_CrcEventGet(CANFDSPI_MODULE_ID index, CAN_CRC_EVENT* flags)
02528 {
02529     int8_t spiTransferError = 0;
02530     uint16_t a = 0;
02531 
02532     // Read interrupt flags of CRC Register
02533     a = cREGADDR_CRC + 2;
02534     uint8_t crc;
02535 
02536     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &crc);
02537     if (spiTransferError) {
02538         return -1;
02539     }
02540 
02541     // Update data
02542     *flags = (CAN_CRC_EVENT) (crc & CAN_CRC_ALL_EVENTS);
02543 
02544     return spiTransferError;
02545 }
02546 
02547 int8_t DRV_CANFDSPI_CrcValueGet(CANFDSPI_MODULE_ID index, uint16_t* crc)
02548 {
02549     int8_t spiTransferError = 0;
02550 
02551     // Read CRC value from CRC Register
02552     spiTransferError = DRV_CANFDSPI_ReadHalfWord(index, cREGADDR_CRC, crc);
02553 
02554     return spiTransferError;
02555 }
02556 
02557 int8_t DRV_CANFDSPI_RamInit(CANFDSPI_MODULE_ID index, uint8_t d)
02558 {
02559     uint8_t txd[SPI_DEFAULT_BUFFER_LENGTH];
02560     uint32_t k;
02561     int8_t spiTransferError = 0;
02562 
02563     // Prepare data
02564     for (k = 0; k < SPI_DEFAULT_BUFFER_LENGTH; k++) {
02565         txd[k] = d;
02566     }
02567 
02568     uint16_t a = cRAMADDR_START;
02569 
02570     for (k = 0; k < (cRAM_SIZE / SPI_DEFAULT_BUFFER_LENGTH); k++) {
02571         spiTransferError = DRV_CANFDSPI_WriteByteArray(index, a, txd, SPI_DEFAULT_BUFFER_LENGTH);
02572         if (spiTransferError) {
02573             return -1;
02574         }
02575         a += SPI_DEFAULT_BUFFER_LENGTH;
02576     }
02577 
02578     return spiTransferError;
02579 }
02580 
02581 
02582 // *****************************************************************************
02583 // *****************************************************************************
02584 // Section: Time Stamp
02585 
02586 int8_t DRV_CANFDSPI_TimeStampEnable(CANFDSPI_MODULE_ID index)
02587 {
02588     int8_t spiTransferError = 0;
02589     uint8_t d = 0;
02590 
02591     // Read
02592     spiTransferError = DRV_CANFDSPI_ReadByte(index, cREGADDR_CiTSCON + 2, &d);
02593     if (spiTransferError) {
02594         return -1;
02595     }
02596 
02597     // Modify
02598     d |= 0x01;
02599 
02600     // Write
02601     spiTransferError = DRV_CANFDSPI_WriteByte(index, cREGADDR_CiTSCON + 2, d);
02602     if (spiTransferError) {
02603         return -2;
02604     }
02605 
02606     return spiTransferError;
02607 }
02608 
02609 int8_t DRV_CANFDSPI_TimeStampDisable(CANFDSPI_MODULE_ID index)
02610 {
02611     int8_t spiTransferError = 0;
02612     uint8_t d = 0;
02613 
02614     // Read
02615     spiTransferError = DRV_CANFDSPI_ReadByte(index, cREGADDR_CiTSCON + 2, &d);
02616     if (spiTransferError) {
02617         return -1;
02618     }
02619 
02620     // Modify
02621     d &= 0x06;
02622 
02623     // Write
02624     spiTransferError = DRV_CANFDSPI_WriteByte(index, cREGADDR_CiTSCON + 2, d);
02625     if (spiTransferError) {
02626         return -2;
02627     }
02628 
02629     return spiTransferError;
02630 }
02631 
02632 int8_t DRV_CANFDSPI_TimeStampGet(CANFDSPI_MODULE_ID index, uint32_t* ts)
02633 {
02634     int8_t spiTransferError = 0;
02635 
02636     // Read
02637     spiTransferError = DRV_CANFDSPI_ReadWord(index, cREGADDR_CiTBC, ts);
02638 
02639     return spiTransferError;
02640 }
02641 
02642 int8_t DRV_CANFDSPI_TimeStampSet(CANFDSPI_MODULE_ID index, uint32_t ts)
02643 {
02644     int8_t spiTransferError = 0;
02645 
02646     // Write
02647     spiTransferError = DRV_CANFDSPI_WriteWord(index, cREGADDR_CiTBC, ts);
02648 
02649     return spiTransferError;
02650 }
02651 
02652 int8_t DRV_CANFDSPI_TimeStampModeConfigure(CANFDSPI_MODULE_ID index,
02653         CAN_TS_MODE mode)
02654 {
02655     int8_t spiTransferError = 0;
02656     uint8_t d = 0;
02657 
02658     // Read
02659     spiTransferError = DRV_CANFDSPI_ReadByte(index, cREGADDR_CiTSCON + 2, &d);
02660     if (spiTransferError) {
02661         return -1;
02662     }
02663 
02664     // Modify
02665     d &= 0x01;
02666     d |= mode << 1;
02667 
02668     // Write
02669     spiTransferError = DRV_CANFDSPI_WriteByte(index, cREGADDR_CiTSCON + 2, d);
02670     if (spiTransferError) {
02671         return -2;
02672     }
02673 
02674     return spiTransferError;
02675 }
02676 
02677 int8_t DRV_CANFDSPI_TimeStampPrescalerSet(CANFDSPI_MODULE_ID index,
02678         uint16_t ps)
02679 {
02680     int8_t spiTransferError = 0;
02681 
02682     // Write
02683     spiTransferError = DRV_CANFDSPI_WriteHalfWord(index, cREGADDR_CiTSCON, ps);
02684 
02685     return spiTransferError;
02686 }
02687 
02688 
02689 // *****************************************************************************
02690 // *****************************************************************************
02691 // Section: Oscillator and Bit Time
02692 
02693 int8_t DRV_CANFDSPI_OscillatorEnable(CANFDSPI_MODULE_ID index)
02694 {
02695     int8_t spiTransferError = 0;
02696     uint8_t d = 0;
02697 
02698     // Read
02699     spiTransferError = DRV_CANFDSPI_ReadByte(index, cREGADDR_OSC, &d);
02700     if (spiTransferError) {
02701         return -1;
02702     }
02703 
02704     // Modify
02705     d &= ~0x4;
02706 
02707     // Write
02708     spiTransferError = DRV_CANFDSPI_WriteByte(index, cREGADDR_OSC, d);
02709     if (spiTransferError) {
02710         return -2;
02711     }
02712 
02713     return spiTransferError;
02714 }
02715 
02716 int8_t DRV_CANFDSPI_OscillatorControlSet(CANFDSPI_MODULE_ID index,
02717         CAN_OSC_CTRL ctrl)
02718 {
02719     int8_t spiTransferError = 0;
02720 
02721     REG_OSC osc;
02722     osc.word = 0;
02723 
02724     osc.bF.PllEnable = ctrl.PllEnable;
02725     osc.bF.OscDisable = ctrl.OscDisable;
02726     osc.bF.SCLKDIV = ctrl.SclkDivide;
02727     osc.bF.CLKODIV = ctrl.ClkOutDivide;
02728 
02729     // Write
02730     spiTransferError = DRV_CANFDSPI_WriteByte(index, cREGADDR_OSC, osc.byte[0]);
02731 
02732     return spiTransferError;
02733 }
02734 
02735 int8_t DRV_CANFDSPI_OscillatorControlObjectReset(CAN_OSC_CTRL* ctrl)
02736 {
02737     REG_OSC osc;
02738     osc.word = mcp2517ControlResetValues[0];
02739 
02740     ctrl->PllEnable = osc.bF.PllEnable;
02741     ctrl->OscDisable = osc.bF.OscDisable;
02742     ctrl->SclkDivide = osc.bF.SCLKDIV;
02743     ctrl->ClkOutDivide = osc.bF.CLKODIV;
02744 
02745     return 0;
02746 }
02747 
02748 int8_t DRV_CANFDSPI_OscillatorStatusGet(CANFDSPI_MODULE_ID index,
02749         CAN_OSC_STATUS* status)
02750 {
02751     int8_t spiTransferError = 0;
02752 
02753     REG_OSC osc;
02754     osc.word = 0;
02755     CAN_OSC_STATUS stat;
02756 
02757     // Read
02758     spiTransferError = DRV_CANFDSPI_ReadByte(index, cREGADDR_OSC + 1, &osc.byte[1]);
02759     if (spiTransferError) {
02760         return -1;
02761     }
02762 
02763     stat.PllReady = osc.bF.PllReady;
02764     stat.OscReady = osc.bF.OscReady;
02765     stat.SclkReady = osc.bF.SclkReady;
02766 
02767     *status = stat;
02768 
02769     return spiTransferError;
02770 }
02771 
02772 int8_t DRV_CANFDSPI_BitTimeConfigure(CANFDSPI_MODULE_ID index,
02773         CAN_BITTIME_SETUP bitTime, CAN_SSP_MODE sspMode,
02774         CAN_SYSCLK_SPEED clk)
02775 {
02776     int8_t spiTransferError = 0;
02777 
02778     // Decode clk
02779     switch (clk) {
02780         case CAN_SYSCLK_40M:
02781             spiTransferError = DRV_CANFDSPI_BitTimeConfigureNominal40MHz(index, bitTime);
02782             if (spiTransferError) return spiTransferError;
02783 
02784             spiTransferError = DRV_CANFDSPI_BitTimeConfigureData40MHz(index, bitTime, sspMode);
02785             break;
02786         case CAN_SYSCLK_20M:
02787             spiTransferError = DRV_CANFDSPI_BitTimeConfigureNominal20MHz(index, bitTime);
02788             if (spiTransferError) return spiTransferError;
02789 
02790             spiTransferError = DRV_CANFDSPI_BitTimeConfigureData20MHz(index, bitTime, sspMode);
02791             break;
02792         case CAN_SYSCLK_10M:
02793             spiTransferError = DRV_CANFDSPI_BitTimeConfigureNominal10MHz(index, bitTime);
02794             if (spiTransferError) return spiTransferError;
02795 
02796             spiTransferError = DRV_CANFDSPI_BitTimeConfigureData10MHz(index, bitTime, sspMode);
02797             break;
02798         default:
02799             spiTransferError = -1;
02800             break;
02801     }
02802 
02803     return spiTransferError;
02804 }
02805 
02806 int8_t DRV_CANFDSPI_BitTimeConfigureNominal40MHz(CANFDSPI_MODULE_ID index,
02807         CAN_BITTIME_SETUP bitTime)
02808 {
02809     int8_t spiTransferError = 0;
02810     REG_CiNBTCFG ciNbtcfg;
02811 
02812     ciNbtcfg.word = canControlResetValues[cREGADDR_CiNBTCFG / 4];
02813 
02814     // Arbitration Bit rate
02815     switch (bitTime) {
02816             // All 500K
02817         case CAN_500K_1M:
02818         case CAN_500K_2M:
02819         case CAN_500K_3M:
02820         case CAN_500K_4M:
02821         case CAN_500K_5M:
02822         case CAN_500K_6M7:
02823         case CAN_500K_8M:
02824         case CAN_500K_10M:
02825             ciNbtcfg.bF.BRP = 0;
02826             ciNbtcfg.bF.TSEG1 = 62;
02827             ciNbtcfg.bF.TSEG2 = 15;
02828             ciNbtcfg.bF.SJW = 15;
02829             break;
02830 
02831             // All 250K
02832         case CAN_250K_500K:
02833         case CAN_250K_833K:
02834         case CAN_250K_1M:
02835         case CAN_250K_1M5:
02836         case CAN_250K_2M:
02837         case CAN_250K_3M:
02838         case CAN_250K_4M:
02839             ciNbtcfg.bF.BRP = 0;
02840             ciNbtcfg.bF.TSEG1 = 126;
02841             ciNbtcfg.bF.TSEG2 = 31;
02842             ciNbtcfg.bF.SJW = 31;
02843             break;
02844 
02845         case CAN_1000K_4M:
02846         case CAN_1000K_8M:
02847             ciNbtcfg.bF.BRP = 0;
02848             ciNbtcfg.bF.TSEG1 = 30;
02849             ciNbtcfg.bF.TSEG2 = 7;
02850             ciNbtcfg.bF.SJW = 7;
02851             break;
02852 
02853         case CAN_125K_500K:
02854             ciNbtcfg.bF.BRP = 0;
02855             ciNbtcfg.bF.TSEG1 = 254;
02856             ciNbtcfg.bF.TSEG2 = 63;
02857             ciNbtcfg.bF.SJW = 63;
02858             break;
02859 
02860         default:
02861             return -1;
02862             break;
02863     }
02864 
02865     // Write Bit time registers
02866     spiTransferError = DRV_CANFDSPI_WriteWord(index, cREGADDR_CiNBTCFG, ciNbtcfg.word);
02867 
02868     return spiTransferError;
02869 }
02870 
02871 int8_t DRV_CANFDSPI_BitTimeConfigureData40MHz(CANFDSPI_MODULE_ID index,
02872         CAN_BITTIME_SETUP bitTime, CAN_SSP_MODE sspMode)
02873 {
02874     int8_t spiTransferError = 0;
02875     REG_CiDBTCFG ciDbtcfg;
02876     REG_CiTDC ciTdc;
02877     //    sspMode;
02878 
02879     ciDbtcfg.word = canControlResetValues[cREGADDR_CiDBTCFG / 4];
02880     ciTdc.word = 0;
02881 
02882     // Configure Bit time and sample point
02883     ciTdc.bF.TDCMode = CAN_SSP_MODE_AUTO;
02884     uint32_t tdcValue = 0;
02885 
02886     // Data Bit rate and SSP
02887     switch (bitTime) {
02888         case CAN_500K_1M:
02889             ciDbtcfg.bF.BRP = 0;
02890             ciDbtcfg.bF.TSEG1 = 30;
02891             ciDbtcfg.bF.TSEG2 = 7;
02892             ciDbtcfg.bF.SJW = 7;
02893             // SSP
02894             ciTdc.bF.TDCOffset = 31;
02895             ciTdc.bF.TDCValue = tdcValue;
02896             break;
02897         case CAN_500K_2M:
02898             // Data BR
02899             ciDbtcfg.bF.BRP = 0;
02900             ciDbtcfg.bF.TSEG1 = 14;
02901             ciDbtcfg.bF.TSEG2 = 3;
02902             ciDbtcfg.bF.SJW = 3;
02903             // SSP
02904             ciTdc.bF.TDCOffset = 15;
02905             ciTdc.bF.TDCValue = tdcValue;
02906             break;
02907         case CAN_500K_3M:
02908             // Data BR
02909             ciDbtcfg.bF.BRP = 0;
02910             ciDbtcfg.bF.TSEG1 = 8;
02911             ciDbtcfg.bF.TSEG2 = 2;
02912             ciDbtcfg.bF.SJW = 2;
02913             // SSP
02914             ciTdc.bF.TDCOffset = 9;
02915             ciTdc.bF.TDCValue = tdcValue;
02916             break;
02917         case CAN_500K_4M:
02918         case CAN_1000K_4M:
02919             // Data BR
02920             ciDbtcfg.bF.BRP = 0;
02921             ciDbtcfg.bF.TSEG1 = 6;
02922             ciDbtcfg.bF.TSEG2 = 1;
02923             ciDbtcfg.bF.SJW = 1;
02924             // SSP
02925             ciTdc.bF.TDCOffset = 7;
02926             ciTdc.bF.TDCValue = tdcValue;
02927             break;
02928         case CAN_500K_5M:
02929             // Data BR
02930             ciDbtcfg.bF.BRP = 0;
02931             ciDbtcfg.bF.TSEG1 = 4;
02932             ciDbtcfg.bF.TSEG2 = 1;
02933             ciDbtcfg.bF.SJW = 1;
02934             // SSP
02935             ciTdc.bF.TDCOffset = 5;
02936             ciTdc.bF.TDCValue = tdcValue;
02937             break;
02938         case CAN_500K_6M7:
02939             // Data BR
02940             ciDbtcfg.bF.BRP = 0;
02941             ciDbtcfg.bF.TSEG1 = 3;
02942             ciDbtcfg.bF.TSEG2 = 0;
02943             ciDbtcfg.bF.SJW = 0;
02944             // SSP
02945             ciTdc.bF.TDCOffset = 4;
02946             ciTdc.bF.TDCValue = tdcValue;
02947             break;
02948         case CAN_500K_8M:
02949         case CAN_1000K_8M:
02950             // Data BR
02951             ciDbtcfg.bF.BRP = 0;
02952             ciDbtcfg.bF.TSEG1 = 2;
02953             ciDbtcfg.bF.TSEG2 = 0;
02954             ciDbtcfg.bF.SJW = 0;
02955             // SSP
02956             ciTdc.bF.TDCOffset = 3;
02957             ciTdc.bF.TDCValue = 1;
02958             break;
02959         case CAN_500K_10M:
02960             // Data BR
02961             ciDbtcfg.bF.BRP = 0;
02962             ciDbtcfg.bF.TSEG1 = 1;
02963             ciDbtcfg.bF.TSEG2 = 0;
02964             ciDbtcfg.bF.SJW = 0;
02965             // SSP
02966             ciTdc.bF.TDCOffset = 2;
02967             ciTdc.bF.TDCValue = 0;
02968             break;
02969 
02970         case CAN_250K_500K:
02971         case CAN_125K_500K:
02972             ciDbtcfg.bF.BRP = 1;
02973             ciDbtcfg.bF.TSEG1 = 30;
02974             ciDbtcfg.bF.TSEG2 = 7;
02975             ciDbtcfg.bF.SJW = 7;
02976             // SSP
02977             ciTdc.bF.TDCOffset = 31;
02978             ciTdc.bF.TDCValue = tdcValue;
02979             ciTdc.bF.TDCMode = CAN_SSP_MODE_OFF;
02980             break;
02981         case CAN_250K_833K:
02982             ciDbtcfg.bF.BRP = 1;
02983             ciDbtcfg.bF.TSEG1 = 17;
02984             ciDbtcfg.bF.TSEG2 = 4;
02985             ciDbtcfg.bF.SJW = 4;
02986             // SSP
02987             ciTdc.bF.TDCOffset = 18;
02988             ciTdc.bF.TDCValue = tdcValue;
02989             ciTdc.bF.TDCMode = CAN_SSP_MODE_OFF;
02990             break;
02991         case CAN_250K_1M:
02992             ciDbtcfg.bF.BRP = 0;
02993             ciDbtcfg.bF.TSEG1 = 30;
02994             ciDbtcfg.bF.TSEG2 = 7;
02995             ciDbtcfg.bF.SJW = 7;
02996             // SSP
02997             ciTdc.bF.TDCOffset = 31;
02998             ciTdc.bF.TDCValue = tdcValue;
02999             break;
03000         case CAN_250K_1M5:
03001             ciDbtcfg.bF.BRP = 0;
03002             ciDbtcfg.bF.TSEG1 = 18;
03003             ciDbtcfg.bF.TSEG2 = 5;
03004             ciDbtcfg.bF.SJW = 5;
03005             // SSP
03006             ciTdc.bF.TDCOffset = 19;
03007             ciTdc.bF.TDCValue = tdcValue;
03008             break;
03009         case CAN_250K_2M:
03010             ciDbtcfg.bF.BRP = 0;
03011             ciDbtcfg.bF.TSEG1 = 14;
03012             ciDbtcfg.bF.TSEG2 = 3;
03013             ciDbtcfg.bF.SJW = 3;
03014             // SSP
03015             ciTdc.bF.TDCOffset = 15;
03016             ciTdc.bF.TDCValue = tdcValue;
03017             break;
03018         case CAN_250K_3M:
03019             ciDbtcfg.bF.BRP = 0;
03020             ciDbtcfg.bF.TSEG1 = 8;
03021             ciDbtcfg.bF.TSEG2 = 2;
03022             ciDbtcfg.bF.SJW = 2;
03023             // SSP
03024             ciTdc.bF.TDCOffset = 9;
03025             ciTdc.bF.TDCValue = tdcValue;
03026             break;
03027         case CAN_250K_4M:
03028             // Data BR
03029             ciDbtcfg.bF.BRP = 0;
03030             ciDbtcfg.bF.TSEG1 = 6;
03031             ciDbtcfg.bF.TSEG2 = 1;
03032             ciDbtcfg.bF.SJW = 1;
03033             // SSP
03034             ciTdc.bF.TDCOffset = 7;
03035             ciTdc.bF.TDCValue = tdcValue;
03036             break;
03037 
03038         default:
03039             return -1;
03040             break;
03041     }
03042 
03043     // Write Bit time registers
03044     spiTransferError = DRV_CANFDSPI_WriteWord(index, cREGADDR_CiDBTCFG, ciDbtcfg.word);
03045     if (spiTransferError) {
03046         return -2;
03047     }
03048 
03049     // Write Transmitter Delay Compensation
03050 #ifdef REV_A
03051     ciTdc.bF.TDCOffset = 0;
03052     ciTdc.bF.TDCValue = 0;
03053 #endif
03054 
03055     spiTransferError = DRV_CANFDSPI_WriteWord(index, cREGADDR_CiTDC, ciTdc.word);
03056     if (spiTransferError) {
03057         return -3;
03058     }
03059 
03060     return spiTransferError;
03061 }
03062 
03063 int8_t DRV_CANFDSPI_BitTimeConfigureNominal20MHz(CANFDSPI_MODULE_ID index,
03064         CAN_BITTIME_SETUP bitTime)
03065 {
03066     int8_t spiTransferError = 0;
03067     REG_CiNBTCFG ciNbtcfg;
03068 
03069     ciNbtcfg.word = canControlResetValues[cREGADDR_CiNBTCFG / 4];
03070 
03071     // Arbitration Bit rate
03072     switch (bitTime) {
03073             // All 500K
03074         case CAN_500K_1M:
03075         case CAN_500K_2M:
03076         case CAN_500K_4M:
03077         case CAN_500K_5M:
03078         case CAN_500K_6M7:
03079         case CAN_500K_8M:
03080         case CAN_500K_10M:
03081             ciNbtcfg.bF.BRP = 0;
03082             ciNbtcfg.bF.TSEG1 = 30;
03083             ciNbtcfg.bF.TSEG2 = 7;
03084             ciNbtcfg.bF.SJW = 7;
03085             break;
03086 
03087             // All 250K
03088         case CAN_250K_500K:
03089         case CAN_250K_833K:
03090         case CAN_250K_1M:
03091         case CAN_250K_1M5:
03092         case CAN_250K_2M:
03093         case CAN_250K_3M:
03094         case CAN_250K_4M:
03095             ciNbtcfg.bF.BRP = 0;
03096             ciNbtcfg.bF.TSEG1 = 62;
03097             ciNbtcfg.bF.TSEG2 = 15;
03098             ciNbtcfg.bF.SJW = 15;
03099             break;
03100 
03101         case CAN_1000K_4M:
03102         case CAN_1000K_8M:
03103             ciNbtcfg.bF.BRP = 0;
03104             ciNbtcfg.bF.TSEG1 = 14;
03105             ciNbtcfg.bF.TSEG2 = 3;
03106             ciNbtcfg.bF.SJW = 3;
03107             break;
03108 
03109         case CAN_125K_500K:
03110             ciNbtcfg.bF.BRP = 0;
03111             ciNbtcfg.bF.TSEG1 = 126;
03112             ciNbtcfg.bF.TSEG2 = 31;
03113             ciNbtcfg.bF.SJW = 31;
03114             break;
03115 
03116         default:
03117             return -1;
03118             break;
03119     }
03120 
03121     // Write Bit time registers
03122     spiTransferError = DRV_CANFDSPI_WriteWord(index, cREGADDR_CiNBTCFG, ciNbtcfg.word);
03123     if (spiTransferError) {
03124         return -2;
03125     }
03126 
03127     return spiTransferError;
03128 }
03129 
03130 int8_t DRV_CANFDSPI_BitTimeConfigureData20MHz(CANFDSPI_MODULE_ID index,
03131         CAN_BITTIME_SETUP bitTime, CAN_SSP_MODE sspMode)
03132 {
03133     int8_t spiTransferError = 0;
03134     REG_CiDBTCFG ciDbtcfg;
03135     REG_CiTDC ciTdc;
03136     //    sspMode;
03137 
03138     ciDbtcfg.word = canControlResetValues[cREGADDR_CiDBTCFG / 4];
03139     ciTdc.word = 0;
03140 
03141     // Configure Bit time and sample point
03142     ciTdc.bF.TDCMode = CAN_SSP_MODE_AUTO;
03143     uint32_t tdcValue = 0;
03144 
03145     // Data Bit rate and SSP
03146     switch (bitTime) {
03147         case CAN_500K_1M:
03148             ciDbtcfg.bF.BRP = 0;
03149             ciDbtcfg.bF.TSEG1 = 14;
03150             ciDbtcfg.bF.TSEG2 = 3;
03151             ciDbtcfg.bF.SJW = 3;
03152             // SSP
03153             ciTdc.bF.TDCOffset = 15;
03154             ciTdc.bF.TDCValue = tdcValue;
03155             break;
03156         case CAN_500K_2M:
03157             // Data BR
03158             ciDbtcfg.bF.BRP = 0;
03159             ciDbtcfg.bF.TSEG1 = 6;
03160             ciDbtcfg.bF.TSEG2 = 1;
03161             ciDbtcfg.bF.SJW = 1;
03162             // SSP
03163             ciTdc.bF.TDCOffset = 7;
03164             ciTdc.bF.TDCValue = tdcValue;
03165             break;
03166         case CAN_500K_4M:
03167         case CAN_1000K_4M:
03168             // Data BR
03169             ciDbtcfg.bF.BRP = 0;
03170             ciDbtcfg.bF.TSEG1 = 2;
03171             ciDbtcfg.bF.TSEG2 = 0;
03172             ciDbtcfg.bF.SJW = 0;
03173             // SSP
03174             ciTdc.bF.TDCOffset = 3;
03175             ciTdc.bF.TDCValue = tdcValue;
03176             break;
03177         case CAN_500K_5M:
03178             // Data BR
03179             ciDbtcfg.bF.BRP = 0;
03180             ciDbtcfg.bF.TSEG1 = 1;
03181             ciDbtcfg.bF.TSEG2 = 0;
03182             ciDbtcfg.bF.SJW = 0;
03183             // SSP
03184             ciTdc.bF.TDCOffset = 2;
03185             ciTdc.bF.TDCValue = tdcValue;
03186             break;
03187         case CAN_500K_6M7:
03188         case CAN_500K_8M:
03189         case CAN_500K_10M:
03190         case CAN_1000K_8M:
03191             //qDebug("Data Bitrate not feasible with this clock!");
03192             return -1;
03193             break;
03194 
03195         case CAN_250K_500K:
03196         case CAN_125K_500K:
03197             ciDbtcfg.bF.BRP = 0;
03198             ciDbtcfg.bF.TSEG1 = 30;
03199             ciDbtcfg.bF.TSEG2 = 7;
03200             ciDbtcfg.bF.SJW = 7;
03201             // SSP
03202             ciTdc.bF.TDCOffset = 31;
03203             ciTdc.bF.TDCValue = tdcValue;
03204             ciTdc.bF.TDCMode = CAN_SSP_MODE_OFF;
03205             break;
03206         case CAN_250K_833K:
03207             ciDbtcfg.bF.BRP = 0;
03208             ciDbtcfg.bF.TSEG1 = 17;
03209             ciDbtcfg.bF.TSEG2 = 4;
03210             ciDbtcfg.bF.SJW = 4;
03211             // SSP
03212             ciTdc.bF.TDCOffset = 18;
03213             ciTdc.bF.TDCValue = tdcValue;
03214             ciTdc.bF.TDCMode = CAN_SSP_MODE_OFF;
03215             break;
03216         case CAN_250K_1M:
03217             ciDbtcfg.bF.BRP = 0;
03218             ciDbtcfg.bF.TSEG1 = 14;
03219             ciDbtcfg.bF.TSEG2 = 3;
03220             ciDbtcfg.bF.SJW = 3;
03221             // SSP
03222             ciTdc.bF.TDCOffset = 15;
03223             ciTdc.bF.TDCValue = tdcValue;
03224             break;
03225         case CAN_250K_1M5:
03226             ciDbtcfg.bF.BRP = 0;
03227             ciDbtcfg.bF.TSEG1 = 8;
03228             ciDbtcfg.bF.TSEG2 = 2;
03229             ciDbtcfg.bF.SJW = 2;
03230             // SSP
03231             ciTdc.bF.TDCOffset = 9;
03232             ciTdc.bF.TDCValue = tdcValue;
03233             break;
03234         case CAN_250K_2M:
03235             ciDbtcfg.bF.BRP = 0;
03236             ciDbtcfg.bF.TSEG1 = 6;
03237             ciDbtcfg.bF.TSEG2 = 1;
03238             ciDbtcfg.bF.SJW = 1;
03239             // SSP
03240             ciTdc.bF.TDCOffset = 7;
03241             ciTdc.bF.TDCValue = tdcValue;
03242             break;
03243         case CAN_250K_3M:
03244             //qDebug("Data Bitrate not feasible with this clock!");
03245             return -1;
03246             break;
03247         case CAN_250K_4M:
03248             // Data BR
03249             ciDbtcfg.bF.BRP = 0;
03250             ciDbtcfg.bF.TSEG1 = 2;
03251             ciDbtcfg.bF.TSEG2 = 0;
03252             ciDbtcfg.bF.SJW = 0;
03253             // SSP
03254             ciTdc.bF.TDCOffset = 3;
03255             ciTdc.bF.TDCValue = tdcValue;
03256             break;
03257 
03258         default:
03259             return -1;
03260             break;
03261     }
03262 
03263     // Write Bit time registers
03264     spiTransferError = DRV_CANFDSPI_WriteWord(index, cREGADDR_CiDBTCFG, ciDbtcfg.word);
03265     if (spiTransferError) {
03266         return -2;
03267     }
03268 
03269     // Write Transmitter Delay Compensation
03270 #ifdef REV_A
03271     ciTdc.bF.TDCOffset = 0;
03272     ciTdc.bF.TDCValue = 0;
03273 #endif
03274 
03275     spiTransferError = DRV_CANFDSPI_WriteWord(index, cREGADDR_CiTDC, ciTdc.word);
03276     if (spiTransferError) {
03277         return -3;
03278     }
03279 
03280     return spiTransferError;
03281 }
03282 
03283 int8_t DRV_CANFDSPI_BitTimeConfigureNominal10MHz(CANFDSPI_MODULE_ID index,
03284         CAN_BITTIME_SETUP bitTime)
03285 {
03286     int8_t spiTransferError = 0;
03287     REG_CiNBTCFG ciNbtcfg;
03288 
03289     ciNbtcfg.word = canControlResetValues[cREGADDR_CiNBTCFG / 4];
03290 
03291     // Arbitration Bit rate
03292     switch (bitTime) {
03293             // All 500K
03294         case CAN_500K_1M:
03295         case CAN_500K_2M:
03296         case CAN_500K_4M:
03297         case CAN_500K_5M:
03298         case CAN_500K_6M7:
03299         case CAN_500K_8M:
03300         case CAN_500K_10M:
03301             ciNbtcfg.bF.BRP = 0;
03302             ciNbtcfg.bF.TSEG1 = 14;
03303             ciNbtcfg.bF.TSEG2 = 3;
03304             ciNbtcfg.bF.SJW = 3;
03305             break;
03306 
03307             // All 250K
03308         case CAN_250K_500K:
03309         case CAN_250K_833K:
03310         case CAN_250K_1M:
03311         case CAN_250K_1M5:
03312         case CAN_250K_2M:
03313         case CAN_250K_3M:
03314         case CAN_250K_4M:
03315             ciNbtcfg.bF.BRP = 0;
03316             ciNbtcfg.bF.TSEG1 = 30;
03317             ciNbtcfg.bF.TSEG2 = 7;
03318             ciNbtcfg.bF.SJW = 7;
03319             break;
03320 
03321         case CAN_1000K_4M:
03322         case CAN_1000K_8M:
03323             ciNbtcfg.bF.BRP = 0;
03324             ciNbtcfg.bF.TSEG1 = 7;
03325             ciNbtcfg.bF.TSEG2 = 2;
03326             ciNbtcfg.bF.SJW = 2;
03327             break;
03328 
03329         case CAN_125K_500K:
03330             ciNbtcfg.bF.BRP = 0;
03331             ciNbtcfg.bF.TSEG1 = 62;
03332             ciNbtcfg.bF.TSEG2 = 15;
03333             ciNbtcfg.bF.SJW = 15;
03334             break;
03335 
03336         default:
03337             return -1;
03338             break;
03339     }
03340 
03341     // Write Bit time registers
03342     spiTransferError = DRV_CANFDSPI_WriteWord(index, cREGADDR_CiNBTCFG, ciNbtcfg.word);
03343     if (spiTransferError) {
03344         return -2;
03345     }
03346 
03347     return spiTransferError;
03348 }
03349 
03350 int8_t DRV_CANFDSPI_BitTimeConfigureData10MHz(CANFDSPI_MODULE_ID index,
03351         CAN_BITTIME_SETUP bitTime, CAN_SSP_MODE sspMode)
03352 {
03353     int8_t spiTransferError = 0;
03354     REG_CiDBTCFG ciDbtcfg;
03355     REG_CiTDC ciTdc;
03356     //    sspMode;
03357 
03358     ciDbtcfg.word = canControlResetValues[cREGADDR_CiDBTCFG / 4];
03359     ciTdc.word = 0;
03360 
03361     // Configure Bit time and sample point
03362     ciTdc.bF.TDCMode = CAN_SSP_MODE_AUTO;
03363     uint32_t tdcValue = 0;
03364 
03365     // Data Bit rate and SSP
03366     switch (bitTime) {
03367         case CAN_500K_1M:
03368             ciDbtcfg.bF.BRP = 0;
03369             ciDbtcfg.bF.TSEG1 = 6;
03370             ciDbtcfg.bF.TSEG2 = 1;
03371             ciDbtcfg.bF.SJW = 1;
03372             // SSP
03373             ciTdc.bF.TDCOffset = 7;
03374             ciTdc.bF.TDCValue = tdcValue;
03375             break;
03376         case CAN_500K_2M:
03377             // Data BR
03378             ciDbtcfg.bF.BRP = 0;
03379             ciDbtcfg.bF.TSEG1 = 2;
03380             ciDbtcfg.bF.TSEG2 = 0;
03381             ciDbtcfg.bF.SJW = 0;
03382             // SSP
03383             ciTdc.bF.TDCOffset = 3;
03384             ciTdc.bF.TDCValue = tdcValue;
03385             break;
03386         case CAN_500K_4M:
03387         case CAN_500K_5M:
03388         case CAN_500K_6M7:
03389         case CAN_500K_8M:
03390         case CAN_500K_10M:
03391         case CAN_1000K_4M:
03392         case CAN_1000K_8M:
03393             //qDebug("Data Bitrate not feasible with this clock!");
03394             return -1;
03395             break;
03396 
03397         case CAN_250K_500K:
03398         case CAN_125K_500K:
03399             ciDbtcfg.bF.BRP = 0;
03400             ciDbtcfg.bF.TSEG1 = 14;
03401             ciDbtcfg.bF.TSEG2 = 3;
03402             ciDbtcfg.bF.SJW = 3;
03403             // SSP
03404             ciTdc.bF.TDCOffset = 15;
03405             ciTdc.bF.TDCValue = tdcValue;
03406             ciTdc.bF.TDCMode = CAN_SSP_MODE_OFF;
03407             break;
03408         case CAN_250K_833K:
03409             ciDbtcfg.bF.BRP = 0;
03410             ciDbtcfg.bF.TSEG1 = 7;
03411             ciDbtcfg.bF.TSEG2 = 2;
03412             ciDbtcfg.bF.SJW = 2;
03413             // SSP
03414             ciTdc.bF.TDCOffset = 8;
03415             ciTdc.bF.TDCValue = tdcValue;
03416             ciTdc.bF.TDCMode = CAN_SSP_MODE_OFF;
03417             break;
03418         case CAN_250K_1M:
03419             ciDbtcfg.bF.BRP = 0;
03420             ciDbtcfg.bF.TSEG1 = 6;
03421             ciDbtcfg.bF.TSEG2 = 1;
03422             ciDbtcfg.bF.SJW = 1;
03423             // SSP
03424             ciTdc.bF.TDCOffset = 7;
03425             ciTdc.bF.TDCValue = tdcValue;
03426             break;
03427         case CAN_250K_1M5:
03428             //qDebug("Data Bitrate not feasible with this clock!");
03429             return -1;
03430             break;
03431         case CAN_250K_2M:
03432             ciDbtcfg.bF.BRP = 0;
03433             ciDbtcfg.bF.TSEG1 = 2;
03434             ciDbtcfg.bF.TSEG2 = 0;
03435             ciDbtcfg.bF.SJW = 0;
03436             // SSP
03437             ciTdc.bF.TDCOffset = 3;
03438             ciTdc.bF.TDCValue = tdcValue;
03439             break;
03440         case CAN_250K_3M:
03441         case CAN_250K_4M:
03442             //qDebug("Data Bitrate not feasible with this clock!");
03443             return -1;
03444             break;
03445 
03446         default:
03447             return -1;
03448             break;
03449     }
03450 
03451     // Write Bit time registers
03452     spiTransferError = DRV_CANFDSPI_WriteWord(index, cREGADDR_CiDBTCFG, ciDbtcfg.word);
03453     if (spiTransferError) {
03454         return -2;
03455     }
03456 
03457     // Write Transmitter Delay Compensation
03458 #ifdef REV_A
03459     ciTdc.bF.TDCOffset = 0;
03460     ciTdc.bF.TDCValue = 0;
03461 #endif
03462 
03463     spiTransferError = DRV_CANFDSPI_WriteWord(index, cREGADDR_CiTDC, ciTdc.word);
03464     if (spiTransferError) {
03465         return -3;
03466     }
03467 
03468     return spiTransferError;
03469 }
03470 
03471 
03472 // *****************************************************************************
03473 // *****************************************************************************
03474 // Section: GPIO
03475 
03476 int8_t DRV_CANFDSPI_GpioModeConfigure(CANFDSPI_MODULE_ID index,
03477         GPIO_PIN_MODE gpio0, GPIO_PIN_MODE gpio1)
03478 {
03479     int8_t spiTransferError = 0;
03480     uint16_t a = 0;
03481 
03482     // Read
03483     a = cREGADDR_IOCON + 3;
03484     REG_IOCON iocon;
03485     iocon.word = 0;
03486 
03487     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &iocon.byte[3]);
03488     if (spiTransferError) {
03489         return -1;
03490     }
03491 
03492     // Modify
03493     iocon.bF.PinMode0 = gpio0;
03494     iocon.bF.PinMode1 = gpio1;
03495 
03496     // Write
03497     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, iocon.byte[3]);
03498     if (spiTransferError) {
03499         return -2;
03500     }
03501 
03502     return spiTransferError;
03503 }
03504 
03505 int8_t DRV_CANFDSPI_GpioDirectionConfigure(CANFDSPI_MODULE_ID index,
03506         GPIO_PIN_DIRECTION gpio0, GPIO_PIN_DIRECTION gpio1)
03507 {
03508     int8_t spiTransferError = 0;
03509     uint16_t a = 0;
03510 
03511     // Read
03512     a = cREGADDR_IOCON;
03513     REG_IOCON iocon;
03514     iocon.word = 0;
03515 
03516     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &iocon.byte[0]);
03517     if (spiTransferError) {
03518         return -1;
03519     }
03520 
03521     // Modify
03522     iocon.bF.TRIS0 = gpio0;
03523     iocon.bF.TRIS1 = gpio1;
03524 
03525     // Write
03526     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, iocon.byte[0]);
03527     if (spiTransferError) {
03528         return -2;
03529     }
03530 
03531     return spiTransferError;
03532 }
03533 
03534 int8_t DRV_CANFDSPI_GpioStandbyControlEnable(CANFDSPI_MODULE_ID index)
03535 {
03536     int8_t spiTransferError = 0;
03537     uint16_t a = 0;
03538 
03539     // Read
03540     a = cREGADDR_IOCON;
03541     REG_IOCON iocon;
03542     iocon.word = 0;
03543 
03544     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &iocon.byte[0]);
03545     if (spiTransferError) {
03546         return -1;
03547     }
03548 
03549     // Modify
03550     iocon.bF.XcrSTBYEnable = 1;
03551 
03552     // Write
03553     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, iocon.byte[0]);
03554     if (spiTransferError) {
03555         return -2;
03556     }
03557 
03558     return spiTransferError;
03559 }
03560 
03561 int8_t DRV_CANFDSPI_GpioStandbyControlDisable(CANFDSPI_MODULE_ID index)
03562 {
03563     int8_t spiTransferError = 0;
03564     uint16_t a = 0;
03565 
03566     // Read
03567     a = cREGADDR_IOCON;
03568     REG_IOCON iocon;
03569     iocon.word = 0;
03570 
03571     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &iocon.byte[0]);
03572     if (spiTransferError) {
03573         return -1;
03574     }
03575 
03576     // Modify
03577     iocon.bF.XcrSTBYEnable = 0;
03578 
03579     // Write
03580     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, iocon.byte[0]);
03581     if (spiTransferError) {
03582         return -2;
03583     }
03584 
03585     return spiTransferError;
03586 }
03587 
03588 int8_t DRV_CANFDSPI_GpioInterruptPinsOpenDrainConfigure(CANFDSPI_MODULE_ID index,
03589         GPIO_OPEN_DRAIN_MODE mode)
03590 {
03591     int8_t spiTransferError = 0;
03592     uint16_t a = 0;
03593 
03594     // Read
03595     a = cREGADDR_IOCON + 3;
03596     REG_IOCON iocon;
03597     iocon.word = 0;
03598 
03599     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &iocon.byte[3]);
03600     if (spiTransferError) {
03601         return -1;
03602     }
03603 
03604     // Modify
03605     iocon.bF.INTPinOpenDrain = mode;
03606 
03607     // Write
03608     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, iocon.byte[3]);
03609     if (spiTransferError) {
03610         return -2;
03611     }
03612 
03613     return spiTransferError;
03614 }
03615 
03616 int8_t DRV_CANFDSPI_GpioTransmitPinOpenDrainConfigure(CANFDSPI_MODULE_ID index,
03617         GPIO_OPEN_DRAIN_MODE mode)
03618 {
03619     int8_t spiTransferError = 0;
03620     uint16_t a = 0;
03621 
03622     // Read
03623     a = cREGADDR_IOCON + 3;
03624     REG_IOCON iocon;
03625     iocon.word = 0;
03626 
03627     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &iocon.byte[3]);
03628     if (spiTransferError) {
03629         return -1;
03630     }
03631 
03632     // Modify
03633     iocon.bF.TXCANOpenDrain = mode;
03634 
03635     // Write
03636     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, iocon.byte[3]);
03637     if (spiTransferError) {
03638         return -2;
03639     }
03640 
03641     return spiTransferError;
03642 }
03643 
03644 int8_t DRV_CANFDSPI_GpioPinSet(CANFDSPI_MODULE_ID index,
03645         GPIO_PIN_POS pos, GPIO_PIN_STATE latch)
03646 {
03647     int8_t spiTransferError = 0;
03648     uint16_t a = 0;
03649 
03650     // Read
03651     a = cREGADDR_IOCON + 1;
03652     REG_IOCON iocon;
03653     iocon.word = 0;
03654 
03655     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &iocon.byte[1]);
03656     if (spiTransferError) {
03657         return -1;
03658     }
03659 
03660     // Modify
03661     switch (pos) {
03662         case GPIO_PIN_0:
03663             iocon.bF.LAT0 = latch;
03664             break;
03665         case GPIO_PIN_1:
03666             iocon.bF.LAT1 = latch;
03667             break;
03668         default:
03669             return -1;
03670             break;
03671     }
03672 
03673     // Write
03674     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, iocon.byte[1]);
03675     if (spiTransferError) {
03676         return -2;
03677     }
03678 
03679     return spiTransferError;
03680 }
03681 
03682 int8_t DRV_CANFDSPI_GpioPinRead(CANFDSPI_MODULE_ID index,
03683         GPIO_PIN_POS pos, GPIO_PIN_STATE* state)
03684 {
03685     int8_t spiTransferError = 0;
03686     uint16_t a = 0;
03687 
03688     // Read
03689     a = cREGADDR_IOCON + 2;
03690     REG_IOCON iocon;
03691     iocon.word = 0;
03692 
03693     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &iocon.byte[2]);
03694     if (spiTransferError) {
03695         return -1;
03696     }
03697 
03698     // Update data
03699     switch (pos) {
03700         case GPIO_PIN_0:
03701             *state = (GPIO_PIN_STATE) iocon.bF.GPIO0;
03702             break;
03703         case GPIO_PIN_1:
03704             *state = (GPIO_PIN_STATE) iocon.bF.GPIO1;
03705             break;
03706         default:
03707             return -1;
03708             break;
03709     }
03710 
03711     return spiTransferError;
03712 }
03713 
03714 int8_t DRV_CANFDSPI_GpioClockOutputConfigure(CANFDSPI_MODULE_ID index,
03715         GPIO_CLKO_MODE mode)
03716 {
03717     int8_t spiTransferError = 0;
03718     uint16_t a = 0;
03719 
03720     // Read
03721     a = cREGADDR_IOCON + 3;
03722     REG_IOCON iocon;
03723     iocon.word = 0;
03724 
03725     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &iocon.byte[3]);
03726     if (spiTransferError) {
03727         return -1;
03728     }
03729 
03730     // Modify
03731     iocon.bF.SOFOutputEnable = mode;
03732 
03733     // Write
03734     spiTransferError = DRV_CANFDSPI_WriteByte(index, a, iocon.byte[3]);
03735     if (spiTransferError) {
03736         return -2;
03737     }
03738 
03739     return spiTransferError;
03740 }
03741 
03742 
03743 // *****************************************************************************
03744 // *****************************************************************************
03745 // Section: Miscellaneous
03746 
03747 uint32_t DRV_CANFDSPI_DlcToDataBytes(CAN_DLC dlc)
03748 {
03749     uint32_t dataBytesInObject = 0;
03750 
03751 //    Nop();
03752 //    Nop();
03753 
03754     if (dlc < CAN_DLC_12) {
03755         dataBytesInObject = dlc;
03756     } else {
03757         switch (dlc) {
03758             case CAN_DLC_12:
03759                 dataBytesInObject = 12;
03760                 break;
03761             case CAN_DLC_16:
03762                 dataBytesInObject = 16;
03763                 break;
03764             case CAN_DLC_20:
03765                 dataBytesInObject = 20;
03766                 break;
03767             case CAN_DLC_24:
03768                 dataBytesInObject = 24;
03769                 break;
03770             case CAN_DLC_32:
03771                 dataBytesInObject = 32;
03772                 break;
03773             case CAN_DLC_48:
03774                 dataBytesInObject = 48;
03775                 break;
03776             case CAN_DLC_64:
03777                 dataBytesInObject = 64;
03778                 break;
03779             default:
03780                 break;
03781         }
03782     }
03783 
03784     return dataBytesInObject;
03785 }
03786 
03787 int8_t DRV_CANFDSPI_FifoIndexGet(CANFDSPI_MODULE_ID index,
03788         CAN_FIFO_CHANNEL channel, uint8_t* mi)
03789 {
03790     int8_t spiTransferError = 0;
03791     uint16_t a = 0;
03792 
03793     // Read Status register
03794     uint8_t b = 0;
03795     a = cREGADDR_CiFIFOSTA + (channel * CiFIFO_OFFSET);
03796     a += 1; // byte[1]
03797 
03798     spiTransferError = DRV_CANFDSPI_ReadByte(index, a, &b);
03799     if (spiTransferError) {
03800         return -1;
03801     }
03802 
03803     // Update data
03804     *mi = b & 0x1f;
03805 
03806     return spiTransferError;
03807 }
03808 
03809 uint16_t DRV_CANFDSPI_CalculateCRC16(uint8_t* data, uint16_t size)
03810 {
03811     uint16_t init = CRCBASE;
03812     uint8_t index;
03813 
03814     while (size-- != 0) {
03815         index = ((uint8_t*) & init)[CRCUPPER] ^ *data++;
03816         init = (init << 8) ^ crc16_table[index];
03817     }
03818 
03819     return init;
03820 }
03821 
03822 CAN_DLC DRV_CANFDSPI_DataBytesToDlc(uint8_t n)
03823 {
03824     CAN_DLC dlc = CAN_DLC_0;
03825 
03826     if (n <= 4) {
03827         dlc = CAN_DLC_4;
03828     } else if (n <= 8) {
03829         dlc = CAN_DLC_8;
03830     } else if (n <= 12) {
03831         dlc = CAN_DLC_12;
03832     } else if (n <= 16) {
03833         dlc = CAN_DLC_16;
03834     } else if (n <= 20) {
03835         dlc = CAN_DLC_20;
03836     } else if (n <= 24) {
03837         dlc = CAN_DLC_24;
03838     } else if (n <= 32) {
03839         dlc = CAN_DLC_32;
03840     } else if (n <= 48) {
03841         dlc = CAN_DLC_48;
03842     } else if (n <= 64) {
03843         dlc = CAN_DLC_64;
03844     }
03845 
03846     return dlc;
03847 }