Autor Tema: SPI por hardware: modificar CCS  (Leído 3292 veces)

0 Usuarios y 1 Visitante están viendo este tema.

penguin

  • Visitante
SPI por hardware: modificar CCS
« en: 11 de Noviembre de 2009, 18:05:10 »
Hola gente. Trato de modificar una libreria de ccs, la can-mcp2510.c ( controlador can externo). Quiero usar la comunicacion entre pic (18f4550, sin can integrado y con SPI) y el MCP2510 ( controlador CAN) mediante SPI. En la libreria can-mcp2510.c, usa unas funciones, y abajo de todo, "simula" el SPI, o sea, mas bien dicho, usa el SPI como software. Yo necesito hacerlo por HW, pero aprobechar las funciones d esa librería. Para ello, he de cambiar la última parte de la librería. En principio, allá donde ponga output_bit(), output_pin(), deberia cambiarlo por spi_read() o spi_write(). He hecho algunos cambios, que me han parecido correctos, pero ni mucho menos lo son. Son los siguientes :

(pongo un trocito de codigo, para ver lo que solo quiero cambiar):

Código: C
  1. for (i=0;i<16;i++) {  ////////////////////////////////////  Esta es por hardware //////////////////////////////////
  2.  
  3.       EXT_CAN_SI=(spi_write(shift_left(&command[0],2,0)));// ---> ejemplo
  4.       output_high(EXT_CAN_SCK);


este trocito pertenece a toda esta parte  ( que no esta cambiada) :
Código: C
  1. ///////////////////
  2. ///
  3. //
  4. // SPI CODE. Antes por sofware, cambiando funciones para usar SPI por HW.
  5. //
  6. ///
  7. //////////////////
  8.  
  9. //data clocked in on rising edge
  10. //data driven out on falling edge
  11. int mcp2510_read(int address) {
  12.    int command[2];
  13.    int i;
  14.    int data;
  15.  
  16.    command[1]=0x03;
  17.    command[0]=address;
  18.  
  19.    output_low(EXT_CAN_CS);
  20.  
  21.   /* for (i=0;i<16;i++) {  ////////////////////////////////////  Esta es por software //////////////////////////////////
  22.       output_bit(EXT_CAN_SI, shift_left(&command[0],2,0));
  23.       output_high(EXT_CAN_SCK);
  24.       output_low(EXT_CAN_SCK);
  25.    }
  26.    for (i=0;i<8;i++) {
  27.       shift_left(&data,1,input(EXT_CAN_SO));
  28.       output_high(EXT_CAN_SCK);
  29.       output_low(EXT_CAN_SCK);
  30.    }*/
  31.  
  32.    /////////////////////////////////////////////////
  33.  
  34.  for (i=0;i<16;i++) {  ////////////////////////////////////  Esta es por hardware //////////////////////////////////
  35.  
  36.       EXT_CAN_SI=(spi_write(shift_left(&command[0],2,0)));// ---> ejemplo
  37.       output_high(EXT_CAN_SCK);
  38.       output_low(EXT_CAN_SCK);
  39.    }
  40.    for (i=0;i<8;i++) {
  41.       shift_left(&data,1,input(EXT_CAN_SO));
  42.       output_high(EXT_CAN_SCK);
  43.       output_low(EXT_CAN_SCK);
  44.    }
  45.    ////////////////////////////////////////////////
  46.  
  47.    output_high(EXT_CAN_CS);
  48.  
  49.    return(data);
  50. }
  51.  
  52. int mcp2510_status(void) {
  53.    int command;
  54.    int data;
  55.    int i;
  56.  
  57.    command=0xA0;
  58.  
  59.    output_low(EXT_CAN_CS);
  60.  
  61.    for (i=0;i<8;i++) {
  62.       output_bit(EXT_CAN_SI, shift_left(&command,1,0));
  63.       output_high(EXT_CAN_SCK);
  64.       output_low(EXT_CAN_SCK);
  65.    }
  66.    for (i=0;i<8;i++) {
  67.       shift_left(&data,1,input(EXT_CAN_SO));
  68.       output_high(EXT_CAN_SCK);
  69.       output_low(EXT_CAN_SCK);
  70.    }
  71.    for (i=0;i<8;i++) {
  72.       output_high(EXT_CAN_SCK);
  73.       output_low(EXT_CAN_SCK);
  74.    }
  75.  
  76.    output_high(EXT_CAN_CS);
  77.  
  78.    return(data);
  79. }
  80.  
  81.  
  82. void mcp2510_write(int address, int data) {
  83.    int command[3];
  84.    int i;
  85.  
  86.    command[2]=0x02;
  87.    command[1]=address;
  88.    command[0]=data;
  89.  
  90.    output_low(EXT_CAN_CS);
  91.  
  92.    for (i=0;i<24;i++) {
  93.       output_bit(EXT_CAN_SI, shift_left(&command[0],3,0));
  94.       output_high(EXT_CAN_SCK);
  95.       output_low(EXT_CAN_SCK);
  96.    }
  97.  
  98.    output_high(EXT_CAN_CS);
  99. }
  100.  
  101. void mcp2510_command(int command) {
  102.    int i;
  103.  
  104.    output_low(EXT_CAN_CS);
  105.  
  106.    for (i=0;i<8;i++) {
  107.       output_bit(EXT_CAN_SI, shift_left(&command,1,0));
  108.       output_high(EXT_CAN_SCK);
  109.       output_low(EXT_CAN_SCK);
  110.    }
  111.  
  112.    output_high(EXT_CAN_CS);
  113. }
  114.  
  115. void mcp2510_init(void) {
  116.    output_high(EXT_CAN_CS);
  117.    output_low(EXT_CAN_SCK);
  118.  
  119.    #ifdef EXT_CAN_TX0RTS
  120.     output_high(EXT_CAN_TX0RTS);
  121.    #endif
  122.    #ifdef EXT_CAN_TX1RTS
  123.     output_high(EXT_CAN_TX1RTS);
  124.    #endif
  125.    #ifdef EXT_CAN_TX2RTS
  126.     output_high(EXT_CAN_TX2RTS);
  127.    #endif
  128.  
  129.   #ifdef EXT_CAN_TX0RTS
  130.    output_high(EXT_CAN_RESET);
  131.    output_low(EXT_CAN_RESET);
  132.    output_high(EXT_CAN_RESET);
  133.    delay_ms(5);
  134.   #endif
  135.  
  136.    mcp2510_command(0xC0);   //reset
  137.    delay_ms(5);
  138. }


y toda esta parte mas grande se corresponde al archivo "can-mcp2510.c ", que yo después renombraré como "spi-can-mcp2510.c ", ya que la gracia está en que es realmente spi ( o será si puedo...):

Código: C
  1. /////////////////////////////////////////////////////////////////////////
  2. ////                        can-mcp2510.c                            ////
  3. //// CAN Library routines for Microchip's MCP2510 (and compatable)   ////
  4. //// CAN IO expanders.                                               ////
  5. ////                                                                 ////
  6. //// This library provides the following functions:                  ////
  7. ////  (for more information on these functions see the comment       ////
  8. ////   header above each function)                                   ////
  9. ////                                                                 ////
  10. ////    can_init - Configures the MCP2510 CAN peripheral             ////
  11. ////                                                                 ////
  12. ////    can_set_baud - Sets the baud rate control registers          ////
  13. ////                                                                 ////
  14. ////    can_set_mode - Sets the CAN module into a specific mode      ////
  15. ////                                                                 ////
  16. ////    can_set_id - Sets the standard and extended ID               ////
  17. ////                                                                 ////
  18. ////    can_get_id - Gets the standard and extended ID               ////
  19. ////                                                                 ////
  20. ////    can_putd - Sends a message/request with specified ID         ////
  21. ////                                                                 ////
  22. ////    can_getd - Returns specifid message/request and ID           ////
  23. ////                                                                 ////
  24. ////    can_kbhit - Returns true if there is data in one of the      ////
  25. ////                receive buffers                                  ////
  26. ////                                                                 ////
  27. ////    can_tbe - Returns true if the transmit buffer is ready to    ////
  28. ////              send more data                                     ////
  29. ////                                                                 ////
  30. ////    can_abort - Aborts all pending transmissions                 ////
  31. ////                                                                 ////
  32. //// You will need a CAN transeiver to connect CANRX and CANTX       ////
  33. //// pins to CANH and CANL bus lines.                                ////
  34. ////                                                                 ////
  35. //// CCS provides an example, ex_can_ccs_b.c, which shows how to use ////
  36. //// this library with CCS's CAN Prototype board.                    ////
  37. ////                                                                 ////
  38. /////////////////////////////////////////////////////////////////////////
  39. ////                                                                 ////
  40. //// Version History                                                 ////
  41. ////                                                                 ////
  42. ////  Jul 27 04 - can_init() uses CAN_USE_EXTENDED_ID instead of     ////
  43. ////              setting all RX filters to extended.                ////
  44. ////                                                                 ////
  45. ////  Apr 20 04 - Fixed a compling problem.                          ////
  46. ////                                                                 ////
  47. ////  Feb 24 04 - can_get_id() fixed for EID<18:20>.                 ////
  48. ////                                                                 ////
  49. /////////////////////////////////////////////////////////////////////////
  50. ////        (C) Copyright 1996,2003 Custom Computer Services         ////
  51. //// This source code may only be used by licensed users of the CCS  ////
  52. //// C compiler.  This source code may only be distributed to other  ////
  53. //// licensed users of the CCS C compiler.  No other use,            ////
  54. //// reproduction or distribution is permitted without written       ////
  55. //// permission.  Derivative programs created using this software    ////
  56. //// in object code form are not restricted in any way.              ////
  57. /////////////////////////////////////////////////////////////////////////
  58.  
  59. #include <can-mcp2510.h>
  60.  
  61. //IO pins connected to MCP2510
  62. #ifndef EXT_CAN_CS
  63.    #define EXT_CAN_CS   PIN_B1
  64.    #define EXT_CAN_SI   PIN_C1
  65.    #define EXT_CAN_SO   PIN_C0
  66.    #define EXT_CAN_SCK  PIN_C3
  67. //   #define EXT_CAN_RESET   PIN_B5 //CCS library does not use this pin by default
  68. //   #define EXT_CAN_TX0RTS  PIN_C4 //CCS library does not use this pin by default
  69. //   #define EXT_CAN_TX1RTS  PIN_B4 //CCS library does not use this pin by default
  70. //   #define EXT_CAN_TX2RTS  PIN_C2 //CCS library does not use this pin by default
  71. #endif
  72.  
  73. #if CAN_DO_DEBUG
  74.  #define can_debug printf
  75. #else
  76.  #define can_debug
  77. #endif
  78.  
  79.  
  80.  
  81.  
  82. int  prescaler;
  83. int1 clkenable;
  84.  
  85.  
  86. ////////////////////////////////////////////////////////////////////////
  87. //
  88. // can_init()
  89. //
  90. // Initializes MCP2510 CAN peripheral.  Sets the RX filter and masks so the
  91. // CAN peripheral will receive all incoming IDs.  Configures both RX buffers
  92. // to only accept valid valid messages (as opposed to all messages, or all
  93. // extended message, or all standard messages).
  94. //
  95. // The constants (CAN_USE_RX_DOUBLE_BUFFER, CAN_ENABLE_DRIVE_HIGH,
  96. // CAN_ENABLE_CAN_CAPTURE, etc) are given a default define in the can-mcp2510.h file.
  97. // These default values can be overwritten in the main code, but most
  98. // applications will be fine with these defaults.
  99. //
  100. //////////////////////////////////////////////////////////////////////////////
  101. void can_init(void) {
  102.    struct struct_RXB0CTRL b_rxb0ctrl;
  103.  
  104.    mcp2510_init();
  105.  
  106.    can_set_mode(CAN_OP_CONFIG);   //must be in config mode before params can be set
  107.    can_set_baud();
  108.  
  109.    b_rxb0ctrl=0;
  110.    b_rxb0ctrl.rxm=CAN_RX_VALID;
  111.    b_rxb0ctrl.bukt=CAN_USE_RX_DOUBLE_BUFFER;
  112.    mcp2510_write(RXB0CTRL, (int)b_rxb0ctrl);
  113.    mcp2510_write(RXB1CTRL, (int)b_rxb0ctrl);
  114.  
  115.    //if you want to configure the TXnRTS pins, do it here.  default is off
  116.  
  117.    can_set_id(RX0MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID);  //set mask 0 (RX BUFFER 0)
  118.    can_set_id(RX0FILTER0, 0, CAN_USE_EXTENDED_ID);  //set filter 0 of mask 0 (RX BUFFER 0)
  119.    can_set_id(RX0FILTER1, 0, CAN_USE_EXTENDED_ID);  //set filter 1 of mask 0 (RX BUFFER 0)
  120.  
  121.    can_set_id(RX1MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID);  //set mask 1 (RX BUFFER 1)
  122.    can_set_id(RX1FILTER2, 0, CAN_USE_EXTENDED_ID);  //set filter 0 of mask 1 (RX BUFFER 1)
  123.    can_set_id(RX1FILTER3, 0, CAN_USE_EXTENDED_ID);  //set filter 1 of mask 1 (RX BUFFER 1)
  124.    can_set_id(RX1FILTER4, 0, CAN_USE_EXTENDED_ID);  //set filter 2 of mask 1 (RX BUFFER 1)
  125.    can_set_id(RX1FILTER5, 0, CAN_USE_EXTENDED_ID);  //set filter 3 of mask 1 (RX BUFFER 1)
  126.  
  127.    can_set_mode(CAN_OP_NORMAL);
  128. }
  129.  
  130. ////////////////////////////////////////////////////////////////////////
  131. //
  132. // can_set_baud()
  133. //
  134. // Configures the baud rate control registers.  All the defines here
  135. // are defaulted in the can-mcp2510.h file.  These defaults can, and
  136. // probably should, be overwritten in the main code.
  137. //
  138. // Current defaults are set to work with CCS's CAN Prototype board and
  139. // Microchip's MCP250xxx CAN Developers Kit if this PIC is running at 20Mhz.
  140. //
  141. ////////////////////////////////////////////////////////////////////////
  142. void can_set_baud(void) {
  143.    struct struct_CNF1 new_CNF1;
  144.    struct struct_CNF2 new_CNF2;
  145.    struct struct_CNF3 new_CNF3;
  146.  
  147.  
  148.    new_CNF1.brp=CAN_BRG_PRESCALAR;
  149.    new_CNF1.sjw=CAN_BRG_SYNCH_JUMP_WIDTH;
  150.  
  151.    new_CNF2.prseg=CAN_BRG_PROPAGATION_TIME;
  152.    new_CNF2.phseg1=CAN_BRG_PHASE_SEGMENT_1;
  153.    new_CNF2.sam=CAN_BRG_SAM;
  154.    new_CNF2.btlmode=CAN_BRG_SEG_2_PHASE_TS;
  155.  
  156.    new_CNF3.phseg2=CAN_BRG_PHASE_SEGMENT_2;
  157.    new_CNF3.wakfil=CAN_BRG_WAKE_FILTER;
  158.  
  159.    mcp2510_write(CNF1, (int)new_CNF1);
  160.    mcp2510_write(CNF2, (int)new_CNF2);
  161.    mcp2510_write(CNF3, (int)new_CNF3);
  162. }
  163.  
  164. void can_set_mode(CAN_OP_MODE mode) {
  165.    struct struct_CANCTRL old_CANCTRL;
  166.  
  167.    old_CANCTRL=mcp2510_read(CANCTRL);
  168.  
  169.    old_CANCTRL.reqop=mode;
  170.  
  171.    mcp2510_write(CANCTRL, (int)old_CANCTRL);
  172.  
  173.    do {
  174.       old_CANCTRL=mcp2510_read(CANCTRL);
  175.    } while (old_CANCTRL.reqop != mode);
  176.  
  177.  }
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185. ///// void can_set_clk(CAN_OP_MODE prescaler)//////////////////////////////////
  186. ////////////////////////////////////////////////////////////////////////////////
  187. //void can_set_clk(CAN_OP_MODE prescaler) {   // funcio pel presclaer del clock del MCP
  188. void can_set_clk(){     //cambio capçalera perque no vull que retorni res. Crida funcio i executa.
  189.   struct struct_CANCTRL old_CANCTRL;
  190.  
  191.    old_CANCTRL=mcp2510_read(CANCTRL);
  192.   // old_CANCTRL.clkpre=0; // modifica els 2 bits del registre CANCTRL per posar a 1 el escaler
  193.  
  194.   prescaler=0; // 0  es el valor que vull de presclaer (0b00)
  195.  
  196.    old_CANCTRL.clkpre=prescaler;     //********** falta activació del pin!!!!!!!!!!!!!!!!!!!!!!!!!!
  197.  
  198.    mcp2510_write(CANCTRL, (int)old_CANCTRL);
  199.  
  200.    do {
  201.       old_CANCTRL=mcp2510_read(CANCTRL);
  202.    } while (old_CANCTRL.clkpre != prescaler);
  203. }
  204.  
  205. ////////////////////////////////////////////////////////////////////////////////
  206. //void can_set_clken() {   // activar pin clckout del mcp2510
  207. void can_set_clken(int1 cambiaa){     //cambio capçalera perque no vull que retorni res. Crida funcio i executa.
  208.   struct struct_CANCTRL old_CANCTRL;
  209.  
  210.    old_CANCTRL=mcp2510_read(CANCTRL);
  211.  
  212.   //clkenable=0; // 0  es el valor que vull de presclaer (0b00)
  213.  
  214.    //old_CANCTRL.clken=clkenable;     //********** falta activació del pin!!!!!!!!!!!!!!!!!!!!!!!!!!
  215.      old_CANCTRL.clken=cambiaa;
  216.  
  217.    mcp2510_write(CANCTRL, (int)old_CANCTRL);
  218.  
  219.    do {
  220.       old_CANCTRL=mcp2510_read(CANCTRL);
  221.    } while (old_CANCTRL.clkpre != prescaler);
  222. }
  223.  
  224. ////////////////////////////////////////////////////////////////////////
  225. //
  226. // can_set_id()
  227. //
  228. // Configures the xxxxEIDL, xxxxEIDH, xxxxSIDL and xxxxSIDH registers to
  229. // configure the defined buffer to use the specified ID
  230. //
  231. //   Paramaters:
  232. //     addr - pointer to first byte of ID register, starting with xxxxEIDL.
  233. //            For example, a pointer to RXM1EIDL
  234. //     id - ID to set buffer to
  235. //     ext - Set to TRUE if this buffer uses an extended ID, FALSE if not
  236. //
  237. ////////////////////////////////////////////////////////////////////////
  238. void can_set_id(int addr, int32 id, int1 ext) {
  239.    int converted_id[4];
  240.    int *ptr;
  241.  
  242.    ptr=&converted_id[3];   //3=eidl, 2=eidh, 1=sidl, 0=sidh
  243.  
  244.    if (ext) {  //extended
  245.       //eidl
  246.       *ptr=make8(id,0); //0:7
  247.  
  248.       //eidh
  249.       ptr--;
  250.       *ptr=make8(id,1); //8:15
  251.  
  252.       //sidl
  253.       ptr--;
  254.       *ptr=make8(id,2) & 0x03;   //16:17
  255.       *ptr|=(make8(id,2) << 3) & 0xE0; //18:20
  256.       *ptr|=0x08;
  257.  
  258.  
  259.       //sidh
  260.       ptr--;
  261.       *ptr=((make8(id,2) >> 5) & 0x07 ); //21:23
  262.       *ptr|=((make8(id,3) << 3) & 0xF8);//24:28
  263.    }
  264.    else {   //standard
  265.       //eidl
  266.       *ptr=0;
  267.  
  268.       //eidh
  269.       ptr--;
  270.       *ptr=0;
  271.  
  272.       //sidl
  273.       ptr--;
  274.       *ptr=(make8(id,0) << 5) & 0xE0;
  275.  
  276.       //sidh
  277.       ptr--;
  278.       *ptr=(make8(id,0) >> 3) & 0x1F;
  279.       *ptr|=(make8(id,1) << 5) & 0xE0;
  280.    }
  281.  
  282.    //0=eidl, 1=eidh, 2=sidl, 3=sidh
  283.    mcp2510_write(addr--, converted_id[3]);
  284.    mcp2510_write(addr--, converted_id[2]);
  285.    mcp2510_write(addr--, converted_id[1]);
  286.    mcp2510_write(addr, converted_id[0]);
  287. }
  288.  
  289. ////////////////////////////////////////////////////////////////////////
  290. //
  291. // can_get_id()
  292. //
  293. // Returns the ID of the specified buffer.  (The opposite of can_set_id())
  294. // This is used after receiving a message, to see which ID sent the message.
  295. //
  296. //   Paramaters:
  297. //     addr - pointer to first byte of ID register, starting with xxxxEIDL.
  298. //            For example, a pointer to RXM1EIDL
  299. //     ext - Set to TRUE if this buffer uses an extended ID, FALSE if not
  300. //
  301. //   Returns:
  302. //     The ID of the buffer
  303. //
  304. ////////////////////////////////////////////////////////////////////////
  305. int32 can_get_id(int addr, int1 ext) {
  306.    int32 ret;
  307.    int * ptr;
  308.    int converted_id[4];
  309.  
  310.    ptr=&converted_id[3];   //3=eidl, 2=eidh, 1=sidl, 0=sidh
  311.  
  312.    converted_id[3]=mcp2510_read(addr--);
  313.    converted_id[2]=mcp2510_read(addr--);
  314.    converted_id[1]=mcp2510_read(addr--);
  315.    converted_id[0]=mcp2510_read(addr);
  316.  
  317.    ret=0;
  318.  
  319.  
  320.    if (ext) {
  321.       ret=*ptr;  //eidl
  322.  
  323.       ptr--;     //eidh
  324.       ret|=((int32)*ptr << 8);
  325.  
  326.       ptr--;     //sidl
  327.       ret|=((int32)*ptr & 0x03) << 16;
  328.       ret|=((int32)*ptr & 0xE0) << 13;
  329.  
  330.       ptr--;     //sidh
  331.       ret|=((int32)*ptr << 21);
  332.    }
  333.    else {
  334.       ptr-=2;    //sidl
  335.       ret=((int32)*ptr & 0xE0) >> 5;
  336.  
  337.       ptr--;     //sidh
  338.       ret|=((int32)*ptr << 3);
  339.    }
  340.  
  341.    return(ret);
  342. }
  343.  
  344. ////////////////////////////////////////////////////////////////////////
  345. //
  346. // can_putd()
  347. //
  348. // Puts data on a transmit buffer, at which time the CAN peripheral will
  349. // send when the CAN bus becomes available.
  350. //
  351. //    Paramaters:
  352. //       id - ID to transmit data as
  353. //       data - pointer to data to send
  354. //       len - length of data to send
  355. //       priority - priority of message.  The higher the number, the
  356. //                  sooner the CAN peripheral will send the message.
  357. //                  Numbers 0 through 3 are valid.
  358. //       ext - TRUE to use an extended ID, FALSE if not
  359. //       rtr - TRUE to set the RTR (request) bit in the ID, false if NOT
  360. //
  361. //    Returns:
  362. //       If successful, it will return TRUE
  363. //       If un-successful, will return FALSE
  364. //
  365. ////////////////////////////////////////////////////////////////////////
  366. int1 can_putd(int32 id, int * data, int len, int priority, int1 ext, int1 rtr) {
  367.    int i;
  368.    int port;
  369.  
  370.    int TXRXBaD0;
  371.    int TXBaCTRL;
  372.    int TXRXBaEIDL;
  373.    int TXBaDLC;
  374.  
  375.    struct txbNctrl_struct b_TXBaCTRL;
  376.    struct rxbNdlc_struct b_TXBaDLC;
  377.    struct txbNctrl_struct b_TXB0CTRL, b_TXB1CTRL, b_TXB2CTRL;
  378.  
  379.    b_TXB0CTRL=mcp2510_read(TXB0CTRL);
  380.    b_TXB1CTRL=mcp2510_read(TXB1CTRL);
  381.    b_TXB2CTRL=mcp2510_read(TXB2CTRL);
  382.  
  383.     // find emtpy transmitter
  384.     //map access bank addresses to empty transmitter
  385.    if (!b_TXB0CTRL.txreq) {
  386.       TXRXBaD0=TXB0D0;
  387.       TXBaCTRL=TXB0CTRL;
  388.       TXRXBaEIDL=TXB0EIDL;
  389.       TXBaDLC=TXB0DLC;
  390.       port=0;
  391.    }
  392.    else if (!b_TXB1CTRL.txreq) {
  393.       TXRXBaD0=TXB1D0;
  394.       TXBaCTRL=TXB1CTRL;
  395.       TXRXBaEIDL=TXB1EIDL;
  396.       TXBaDLC=TXB1DLC;
  397.       port=1;
  398.    }
  399.    else if (!b_TXB2CTRL.txreq) {
  400.       TXRXBaD0=TXB2D0;
  401.       TXBaCTRL=TXB2CTRL;
  402.       TXRXBaEIDL=TXB2EIDL;
  403.       TXBaDLC=TXB2DLC;
  404.       port=2;
  405.    }
  406.    else {
  407.       #if CAN_DO_DEBUG
  408.          can_debug("\r\nCAN_PUTD() FAIL: NO OPEN TX BUFFERS\r\n");
  409.       #endif
  410.       return(0);
  411.    }
  412.  
  413.    //set priority.
  414.    b_TXBaCTRL=mcp2510_read(TXBaCTRL);
  415.    b_TXBaCTRL.txpri=priority;
  416.    mcp2510_write(TXBaCTRL, (int)b_TXBaCTRL);
  417.  
  418.    //set tx mask
  419.    can_set_id(TXRXBaEIDL, id, ext);
  420.  
  421.    //set tx data count
  422.    b_TXBaDLC=len;
  423.    b_TXBaDLC.rtr=rtr;
  424.    mcp2510_write(TXBaDLC, (int)b_TXBaDLC);
  425.  
  426.    //write to buffer
  427.     for (i=TXRXBaD0; i<(TXRXBaD0 + len); i++) {
  428.       mcp2510_write(i,*data);
  429.       data++;
  430.     }
  431.  
  432.    //enable transmission
  433.    b_TXBaCTRL=mcp2510_read(TXBaCTRL);
  434.    b_TXBaCTRL.txreq=1;
  435.    mcp2510_write(TXBaCTRL, (int)b_TXBaCTRL);
  436.  
  437.    #if CAN_DO_DEBUG
  438.             can_debug("\r\nCAN_PUTD(): BUFF=%U ID=%LX LEN=%U PRI=%U EXT=%U RTR=%U\r\n", port, id, len, priority, ext, rtr);
  439.             if ((len)&&(!rtr)) {
  440.                data-=len;
  441.                can_debug("  DATA = ");
  442.                for (i=0;i<len;i++) {
  443.                   can_debug("%X ",*data);
  444.                   data++;
  445.                }
  446.                can_debug("\r\n");
  447.             }
  448.    #endif
  449.  
  450.    return(1);
  451. }
  452.  
  453. ////////////////////////////////////////////////////////////////////////
  454. //
  455. // can_getd()
  456. //
  457. // Gets data from a receive buffer, if the data exists
  458. //
  459. //    Returns:
  460. //      id - ID who sent message
  461. //      data - pointer to array of data
  462. //      len - length of received data
  463. //      stat - structure holding some information (such as which buffer
  464. //             recieved it, ext or standard, etc)
  465. //
  466. //    Returns:
  467. //      Function call returns a TRUE if there was data in a RX buffer, FALSE
  468. //      if there was none.
  469. //
  470. ////////////////////////////////////////////////////////////////////////
  471. int1 can_getd(int32 & id, int * data, int & len, struct rx_stat & stat)
  472. {
  473.     int i;
  474.  
  475.    struct struct_RXB0CTRL b_RXB0CTRL;
  476.    struct struct_RXB1CTRL b_RXB1CTRL;
  477.    struct struct_EFLG b_EFLG;
  478.  
  479.    int RXBaDLC;
  480.    struct rxbNdlc_struct b_RXBaDLC;
  481.  
  482.    int TXRXBaSIDL;
  483.    struct struct_TXRXBaSIDL b_TXRXBaSIDL;
  484.  
  485.  
  486.    int RXBaD0;
  487.    struct struct_CANINTF b_CANINTF;
  488.  
  489.    b_CANINTF=mcp2510_read(CANINTF);
  490.  
  491.    b_RXB0CTRL=mcp2510_read(RXB0CTRL);
  492.    b_RXB1CTRL=mcp2510_read(RXB1CTRL);
  493.    b_EFLG=mcp2510_read(EFLG);
  494.  
  495.     if (b_CANINTF.rx0if) {
  496.         stat.buffer=0;
  497.  
  498.         stat.err_ovfl=b_EFLG.rx0ovr;
  499.         b_EFLG.rx0ovr=0;
  500.         mcp2510_write(EFLG, (int)b_EFLG);
  501.  
  502.         if (b_RXB0CTRL.bukt) {
  503.          stat.filthit=b_RXB0CTRL.filhit0;
  504.         }
  505.  
  506.         RXBaDLC=RXB0DLC;
  507.         TXRXBaSIDL=RXB0SIDL;
  508.         RXBaD0=RXB0D0;
  509.     }
  510.     else if (b_CANINTF.rx1if)
  511.     {
  512.         stat.buffer=1;
  513.  
  514.         stat.err_ovfl=b_EFLG.rx1ovr;
  515.         b_EFLG.rx1ovr=0;
  516.         mcp2510_write(EFLG, (int)b_EFLG);
  517.  
  518.  
  519.         stat.filthit=b_RXB1CTRL.filhit0;
  520.         RXBaDLC=RXB1DLC;
  521.         TXRXBaSIDL=RXB1SIDL;
  522.         RXBaD0=RXB1D0;
  523.     }
  524.     else {
  525.       #if CAN_DO_DEBUG
  526.          can_debug("\r\nFAIL ON CAN_GETD(): NO MESSAGE IN BUFFER\r\n");
  527.       #endif
  528.       return (0);
  529.     }
  530.  
  531.    //get count
  532.     b_RXBaDLC=mcp2510_read(RXBaDLC);
  533.     len = b_RXBaDLC.dlc;
  534.     stat.rtr=b_RXBaDLC.rtr;
  535.  
  536.    //was it extended or standard?
  537.     b_TXRXBaSIDL=mcp2510_read(TXRXBaSIDL);
  538.     stat.ext=b_TXRXBaSIDL.ext;
  539.     id=can_get_id(TXRXBaSIDL + 2,stat.ext);
  540.  
  541.    //get data
  542.     for ( i = RXBaD0; i < (RXBaD0 + len); i++ ) {
  543.          *data=mcp2510_read(i);
  544.         data++;
  545.     }
  546.  
  547.     stat.inv=b_CANINTF.merrf;
  548.     if (b_CANINTF.merrf) {
  549.       b_CANINTF.merrf=0;
  550.     }
  551.  
  552.     if (stat.buffer) {
  553.       b_CANINTF.rx1if=0;
  554.     }
  555.     else {
  556.       b_CANINTF.rx0if=0;
  557.     }
  558.     mcp2510_write(CANINTF, (int)b_CANINTF);
  559.  
  560.     #if CAN_DO_DEBUG
  561.        can_debug("\r\nCAN_GETD(): BUFF=%U ID=%LX LEN=%U OVF=%U ", stat.buffer, id, len, stat.err_ovfl);
  562.        can_debug("FILT=%U RTR=%U EXT=%U INV=%U", stat.filthit, stat.rtr, stat.ext, stat.inv);
  563.        if ((len)&&(!stat.rtr)) {
  564.           data-=len;
  565.           can_debug("\r\n    DATA = ");
  566.           for (i=0;i<len;i++) {
  567.             can_debug("%X ",*data);
  568.             data++;
  569.           }
  570.        }
  571.        can_debug("\r\n");
  572.     #endif
  573.  
  574.     return(1);
  575. }
  576.  
  577. ////////////////////////////////////////////////////////////////////////
  578. //
  579. // can_kbhit()
  580. //
  581. // Returns TRUE if there is data in the receive buffers
  582. //
  583. //////////////////////////////////////////////////////////////////////////////
  584. int1 can_kbhit(void) {
  585.    struct struct_CANINTF b_CANINTF;
  586.  
  587.    b_CANINTF=mcp2510_read(CANINTF);
  588.    if (b_CANINTF.rx0if || b_CANINTF.rx1if)
  589.       {return(1);}
  590.  
  591.    return(0);
  592. }
  593.  
  594. ////////////////////////////////////////////////////////////////////////
  595. //
  596. // can_tbe()
  597. //
  598. // Returns TRUE if the transmit buffers are empty and ready to transmit data
  599. //
  600. //////////////////////////////////////////////////////////////////////////////
  601. int1 can_tbe(void) {
  602.    struct txbNctrl_struct b_TXB0CTRL, b_TXB1CTRL, b_TXB2CTRL;
  603.  
  604.    b_TXB0CTRL=mcp2510_read(TXB0CTRL);
  605.    b_TXB1CTRL=mcp2510_read(TXB1CTRL);
  606.    b_TXB2CTRL=mcp2510_read(TXB2CTRL);
  607.  
  608.    if (!b_TXB0CTRL.txreq || !b_TXB1CTRL.txreq || !b_TXB2CTRL.txreq)
  609.       {return(1);}
  610.  
  611.    return(0);
  612. }
  613.  
  614. ////////////////////////////////////////////////////////////////////////
  615. //
  616. // can_abort()
  617. //
  618. // Aborts all pending tranmissions.
  619. //
  620. //////////////////////////////////////////////////////////////////////////////
  621. void can_abort(void) {
  622.    struct struct_CANCTRL b_CANCTRL;
  623.  
  624.    b_CANCTRL=mcp2510_read(CANCTRL);
  625.    b_CANCTRL.abat=1;
  626.    mcp2510_write(CANCTRL, (int)b_CANCTRL);
  627.  
  628.    delay_ms(5);
  629.    b_CANCTRL.abat=0;
  630.    mcp2510_write(CANCTRL, (int)b_CANCTRL);
  631. }
  632.  
  633.  
  634.  
  635.  
  636. ///////////////////
  637. ///
  638. //
  639. // SPI CODE. Antes por sofware, cambiando funciones para usar SPI por HW.
  640. //
  641. ///
  642. //////////////////
  643.  
  644. //data clocked in on rising edge
  645. //data driven out on falling edge
  646. int mcp2510_read(int address) {
  647.    int command[2];
  648.    int i;
  649.    int data;
  650.  
  651.    command[1]=0x03;
  652.    command[0]=address;
  653.  
  654.    output_low(EXT_CAN_CS);
  655.  
  656.   /* for (i=0;i<16;i++) {  ////////////////////////////////////  Esta es por software //////////////////////////////////
  657.       output_bit(EXT_CAN_SI, shift_left(&command[0],2,0));
  658.       output_high(EXT_CAN_SCK);
  659.       output_low(EXT_CAN_SCK);
  660.    }
  661.    for (i=0;i<8;i++) {
  662.       shift_left(&data,1,input(EXT_CAN_SO));
  663.       output_high(EXT_CAN_SCK);
  664.       output_low(EXT_CAN_SCK);
  665.    }*/
  666.  
  667.    /////////////////////////////////////////////////
  668.  
  669.  for (i=0;i<16;i++) {  ////////////////////////////////////  Esta es por hardware //////////////////////////////////
  670.  
  671.       EXT_CAN_SI=(spi_write(shift_left(&command[0],2,0)));// ---> ejemplo
  672.       output_high(EXT_CAN_SCK);
  673.       output_low(EXT_CAN_SCK);
  674.    }
  675.    for (i=0;i<8;i++) {
  676.       shift_left(&data,1,input(EXT_CAN_SO));
  677.       output_high(EXT_CAN_SCK);
  678.       output_low(EXT_CAN_SCK);
  679.    }
  680.    ////////////////////////////////////////////////
  681.  
  682.    output_high(EXT_CAN_CS);
  683.  
  684.    return(data);
  685. }
  686.  
  687. int mcp2510_status(void) {
  688.    int command;
  689.    int data;
  690.    int i;
  691.  
  692.    command=0xA0;
  693.  
  694.    output_low(EXT_CAN_CS);
  695.  
  696.    for (i=0;i<8;i++) {
  697.       output_bit(EXT_CAN_SI, shift_left(&command,1,0));
  698.       output_high(EXT_CAN_SCK);
  699.       output_low(EXT_CAN_SCK);
  700.    }
  701.    for (i=0;i<8;i++) {
  702.       shift_left(&data,1,input(EXT_CAN_SO));
  703.       output_high(EXT_CAN_SCK);
  704.       output_low(EXT_CAN_SCK);
  705.    }
  706.    for (i=0;i<8;i++) {
  707.       output_high(EXT_CAN_SCK);
  708.       output_low(EXT_CAN_SCK);
  709.    }
  710.  
  711.    output_high(EXT_CAN_CS);
  712.  
  713.    return(data);
  714. }
  715.  
  716.  
  717. void mcp2510_write(int address, int data) {
  718.    int command[3];
  719.    int i;
  720.  
  721.    command[2]=0x02;
  722.    command[1]=address;
  723.    command[0]=data;
  724.  
  725.    output_low(EXT_CAN_CS);
  726.  
  727.    for (i=0;i<24;i++) {
  728.       output_bit(EXT_CAN_SI, shift_left(&command[0],3,0));
  729.       output_high(EXT_CAN_SCK);
  730.       output_low(EXT_CAN_SCK);
  731.    }
  732.  
  733.    output_high(EXT_CAN_CS);
  734. }
  735.  
  736. void mcp2510_command(int command) {
  737.    int i;
  738.  
  739.    output_low(EXT_CAN_CS);
  740.  
  741.    for (i=0;i<8;i++) {
  742.       output_bit(EXT_CAN_SI, shift_left(&command,1,0));
  743.       output_high(EXT_CAN_SCK);
  744.       output_low(EXT_CAN_SCK);
  745.    }
  746.  
  747.    output_high(EXT_CAN_CS);
  748. }
  749.  
  750. void mcp2510_init(void) {
  751.    output_high(EXT_CAN_CS);
  752.    output_low(EXT_CAN_SCK);
  753.  
  754.    #ifdef EXT_CAN_TX0RTS
  755.     output_high(EXT_CAN_TX0RTS);
  756.    #endif
  757.    #ifdef EXT_CAN_TX1RTS
  758.     output_high(EXT_CAN_TX1RTS);
  759.    #endif
  760.    #ifdef EXT_CAN_TX2RTS
  761.     output_high(EXT_CAN_TX2RTS);
  762.    #endif
  763.  
  764.   #ifdef EXT_CAN_TX0RTS
  765.    output_high(EXT_CAN_RESET);
  766.    output_low(EXT_CAN_RESET);
  767.    output_high(EXT_CAN_RESET);
  768.    delay_ms(5);
  769.   #endif
  770.  
  771.    mcp2510_command(0xC0);   //reset
  772.    delay_ms(5);
  773. }


el error al compilar es el siguiente :
Código: C
  1. Expecting LVALUE such as a variable name or *expression

Entiendo que lo que estoy haciendo es como usar 5=4, es decir, usar una constante como valor de variable, pero, es que no se me ocurre como escribir mediante SPI de otro modo, para cambiar esa funcion. SI alguien sabe que hacer aqui... Gracias

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: SPI por hardware: modificar CCS
« Respuesta #1 en: 11 de Noviembre de 2009, 20:46:08 »
No, tienes que cambiar todo el for (Que es la rutina que envía o lee bit por bit) por spi_write() o spi_read() (que envía o lee el byte por hard) dependiendo de lo que se haga y utilizar setup_spi() para configurar el módulo. Lo único que no hay que tocar es el CS.

Saludos!
No contesto mensajes privados, las consultas en el foro

penguin

  • Visitante
Re: SPI por hardware: modificar CCS
« Respuesta #2 en: 12 de Noviembre de 2009, 05:14:34 »
Hola Suky, si si , lo se. Se que he de cambiar el for ( todo), pero no lo he cambiado todo , ya que de h ido paso a paso. Si el primer cambio era correcto, es decir, me compilaba ( al menos), los demás cambios seguirían la misma rutina. En cuanto al CS, si, se que se ha de dejar por software, ya que SPI HW solo controla SI, SO y CLK. Pero el hecho es en el que pongo  " -> ejemplo". A partir de que ese cambio funcione, los demas será hacer lo mismo. Eso es lo que no se como modificar poniendo spi_read() o spi_write()

penguin

  • Visitante
Re: SPI por hardware: modificar CCS
« Respuesta #3 en: 12 de Noviembre de 2009, 05:32:36 »
uy, se me olvidaba decir..el setup Spy lo uso desde mi archivo main(), supongo que al poner  ( claro esta :))  #include<can-mcp2510.c> desde el main no hara falta ponerlo en el mismo archivo can-mcp2510.c, ¿ no?

Saludos!

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: SPI por hardware: modificar CCS
« Respuesta #4 en: 12 de Noviembre de 2009, 09:24:00 »
no se puede empezar a cambiar de a poquito, o se cambia todo el for o no se cambia nada, sino no funciona, por ejemplo:

Código: C
  1. for (i=0;i<16;i++) {  /////////////  Esta es por software
  2.      output_bit(EXT_CAN_SI, shift_left(&command[0],2,0));
  3.      output_high(EXT_CAN_SCK);
  4.      output_low(EXT_CAN_SCK);
  5.   }
  6.   for (i=0;i<8;i++) {
  7.      shift_left(&data,1,input(EXT_CAN_SO));
  8.      output_high(EXT_CAN_SCK);
  9.      output_low(EXT_CAN_SCK);
  10.   }

Lo cambiaría por:
Código: C
  1. spi_write(command[0]);
  2.     spi_write(command[1]);
  3.     data=read_spi();

saludos!
No contesto mensajes privados, las consultas en el foro

penguin

  • Visitante
Re: SPI por hardware: modificar CCS
« Respuesta #5 en: 12 de Noviembre de 2009, 09:47:07 »

q tal suky!. Me dices de cambiar a esto :
Código: C
  1. 1.
  2.          spi_write(command[0]);
  3.    2.
  4.          spi_write(command[1]);
  5.    3.
  6.          data=read_spi();

no entiendo la segunda y tercera lineas tuyas, aunque andando si he puesto una cosa bastante parecida a la tuya, es la siguiente ( porque command refleja un valor) :
Código: C
  1. shift_left(&command[0],2,0);   // siempre envia un 0 ( lo va rotando)
  2.  spi_write(command[0]);         // escribe el 0 por patilla SI directamente
aunque no entiendo como hacerlo para
Código: C
  1. for (i=0;i<8;i++) {
  2.       shift_left(&data,1,input(EXT_CAN_SO));
  3.       output_high(EXT_CAN_SCK);
  4.       output_low(EXT_CAN_SCK);
  5.    }
yo lo cambio por
Código: C
  1. for (i=0;i<8;i++) {
  2.      // shift_left(&data,1,input(EXT_CAN_SO));// si hay tension en EXT_CAN_SO da un true, sino false
  3.         if(input(EXT_CAN_SO))
  4.         {
  5.            if (EXT_CAN_SO==true){
  6.                shift_left(&data,1,1);
  7.            }
  8.            if (EXT_CAN_SO==false){
  9.                shift_left(&data,1,0);
  10.            }
  11.  
  12.                                     // elimino lineas dedicadas a sck, ya que lo controla el protocolo SPI directamente
  13.         }
Se que esos if son un poco "bastos" ( podria cambiar por case). Lo que quiero es traducir a SPI, pero  no me convence mucho. ¿ Por que lo digo? input(pin) te da un true si el pin esta en high, y un false si esta en low, entonces shift_left(&data,1,input(EXT_CAN_SO)) gira si hay input o no?? Yo he puesto algo asi como que si es true, quiere dcir que  el valor que ha de rotar es un 1, y al contrario, si es false, el valor que ha de rotar es un 0. Por eso, algo asi como .... " si es true(1) rota un 1. Pero... no encuentro donde rayos he de poner cualquier spi_read() o spi_write en ese apartado ( yo se que esta comparando valor de  EXT_CAN_SO, por tanto dberia haber un read?)

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: SPI por hardware: modificar CCS
« Respuesta #6 en: 12 de Noviembre de 2009, 10:16:21 »
Te conviene leer un poco como trabaja SPI para darte cuenta que se esta haciendo en el código  :? Primero el PIC manda 16 bits, osea command 0 y 1, luego recibe un 8 bits y los guarda en data. Por ello el reemplazo que realice.


Saludos!
No contesto mensajes privados, las consultas en el foro

penguin

  • Visitante
Re: SPI por hardware: modificar CCS
« Respuesta #7 en: 13 de Noviembre de 2009, 06:19:45 »
uhmm si, es cierto. Llevo bastante verde el SPI. Primero da peticion al chip MCP de escritura de un orden ( no se en que buffer concretamente, pero da igual -de todos modos, sabiéndolo, lo podría mirar-). El caso es que la rotación no hace falta porque el propio SPI se encarga de hacerlo. Cuando acabe la librería ( acabar significa probarla con el proyecto y que funcione) la comento por aquí, porque supongo que mas de uno le agradará.

Saludos!!

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: SPI por hardware: modificar CCS
« Respuesta #8 en: 13 de Noviembre de 2009, 11:15:08 »
Exactamente, por software se usan el for para enviar los bits, en cambio por hardware solo cargas el byte a enviar y el módulo se encarga de enviarlo, lo único que se debe configurar correctamente con setup_spi(), en donde seleccionas la frecuencia y el modo de operación.


Saludos!
No contesto mensajes privados, las consultas en el foro