Autor Tema: [SOLUCIONADO] Imposible leer memoria flash spi  (Leído 6125 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
[SOLUCIONADO] Imposible leer memoria flash spi
« en: 17 de Enero de 2013, 12:10:52 »
EDIT: El problema no se resolvió del todo, click aquí para leer por qué.

Buenas amigos!!
Acudo a ustedes porque ya estoy demasiado frustrado. No logro comunicarme con una memoria flash spi (SST26VF016).
Luego de mil intentos y pruebas, llegue al codigo mas simple que puedo hacer. El mismo consulta el registro de estado de la memoria. Pero siempre me devuelve 0x00, como si la memoria no estuviera conectada (tambien consulte otros registros y el resultado es el mismo). Ademas revise el hardware, que este todo bien soldado y haya continuidad en las pistas.
Estoy trabajando con un PIC18F26J50 en CCS. Este es el codigo:

Código: C
  1. #include <18F26J50.h>
  2. #FUSES NOWDT,INTRC_PLL_IO,NODEBUG,NOXINST,STVREN,NOPROTECT,NOFCMEN,IESO,NOIOL1WAY,PRIMARY,NOCPUDIV,LPT1OSC,T1DIG,PLLDIV2                
  3.  
  4. #use delay(clock=48M,INTERNAL)
  5. #include ".\include\usb_cdc.h"
  6.  
  7. #use spi(MASTER,CLK=PIN_B4, DO=PIN_B5, DI=PIN_B2, ENABLE=PIN_B3, MODE=0, STREAM=FLASH, FORCE_SW, BAUD=10000000)
  8.  
  9.  
  10.  
  11.  
  12. void main(){
  13.    int8 recibido=0;
  14.    
  15.    delay_ms(100);
  16.    set_tris_a(0b1110011);  //OSC2,NC,VREG,M95_ON,LED_R,NC,NC
  17.    set_tris_b(0b11000110); //PGD,PGC,SDO2,SCK2,CS,SDI2,RX2,TX2
  18.    set_tris_c(0b10111111); //RX1,TX1,D+,D-,VUSB,NC,T1OSI,T1OSO
  19.    
  20.    output_high(PIN_B3);
  21.  
  22.    usb_cdc_init();
  23.    usb_init();  
  24.    while (!usb_cdc_connected());
  25.    
  26.    delay_ms(100);
  27.    usb_task();
  28.    if(usb_enumerated())
  29.       printf(usb_cdc_putc,"USB conectado\r\n");
  30.    
  31.    
  32.    while(TRUE){
  33.       recibido = spi_xfer(FLASH,0x05);
  34.       printf(usb_cdc_putc,"recibido: %X\r\n",recibido);
  35.      
  36.       output_toggle(PIN_A2);
  37.       delay_ms(500);
  38.    }
  39. }

Como ven, estoy utilizando SPI por software, ya que el error podia estar en la configuracion del modulo spi del pic (estoy usando el spi2 con PPS ya que tuve q reasignar unos pines).
Ven algun error? que me aconsejan?
Muchas gracias!!
« Última modificación: 23 de Enero de 2013, 11:48:39 por gera »

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Imposible leer memoria flash spi
« Respuesta #1 en: 17 de Enero de 2013, 12:25:53 »
Y donde controlas CS o CE? Este habilita la memoria con una transición de alto a bajo.


Edit: Por lo visto lo hace CCS en sus funciones (hace mucho que no lo toco)... Probaste de hacerlo manual o verificaste que señales tenes mediante un osciloscopio o analizador logico?

Saludos!
« Última modificación: 17 de Enero de 2013, 12:28:19 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Imposible leer memoria flash spi
« Respuesta #2 en: 17 de Enero de 2013, 12:47:45 »
Y donde controlas CS o CE? Este habilita la memoria con una transición de alto a bajo.


Edit: Por lo visto lo hace CCS en sus funciones (hace mucho que no lo toco)... Probaste de hacerlo manual o verificaste que señales tenes mediante un osciloscopio o analizador logico?

Saludos!

Gracias por la pronta respuesta!
Previamente controlaba la señal CE manualmente, pero luego vi que podia definirlo en #use spi como ENABLE=PIN_B3. Por defecto es "low active". Justamente lo que estoy necesitando es un analizador logico, lamentablemente no cuento con uno.

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Imposible leer memoria flash spi
« Respuesta #3 en: 17 de Enero de 2013, 13:05:25 »
No probaste con:

Código: [Seleccionar]
CS=0;
spi_xfer(FLASH,0x05);
recibido = spi_xfer(FLASH,0xFF);
CS=1;

Te dejo la librería que implemento en C32:

Código: C
  1. /*
  2.    \file SST25VF016.h  
  3.    \version 1.1
  4.    
  5.    \author Suky.
  6.    \web www.micros-designs.com.ar
  7.    \date 06/10/11  
  8.    
  9.  *- Version Log --------------------------------------------------------------*
  10.  *   Fecha       Autor                Comentarios                             *
  11.  *----------------------------------------------------------------------------*
  12.  * 06/10/11      Suky         Original (Rev 1.0) (C18)                        *
  13.  * 06/12/11              Suky             Para C32
  14.  *----------------------------------------------------------------------------* */
  15. #ifndef _SST25VF016_H
  16.     #define _SST25VF016_H
  17.    
  18. #include <p32xxxx.h>
  19. #include <plib.h>    
  20. #include "GenericTypeDefs.h"
  21. #include "TimeDelay.h"
  22. #include "HardwareProfileSkP32.h"
  23.  
  24. /************************************************************************
  25. * SST25 Commandos                                                      
  26. ************************************************************************/
  27. #define SST25_CMD_READ  (unsigned)0x03
  28. #define SST25_CMD_READH (unsigned)0x0B
  29. #define SST25_CMD_WRITE (unsigned)0x02
  30. #define SST25_CMD_WREN  (unsigned)0x06
  31. #define SST25_CMD_RDSR  (unsigned)0x05
  32. #define SST25_CMD_ERASE (unsigned)0x60
  33. #define SST25_CMD_EWSR  (unsigned)0x50
  34. #define SST25_CMD_WRSR  (unsigned)0x01
  35. #define SST25_CMD_SER   (unsigned)0x20
  36.  
  37.  
  38. void vSST25Init(void);
  39. UINT8 uiSST25IsWriteBusy(void);
  40. void vSST25WriteByte(UINT8 data, UINT32 address);
  41. UINT8 uiSST25ReadByte(UINT32 address);
  42. void vSST25WriteEnable(void);
  43. void vSST25ChipErase(void);
  44. void vSST25ResetWriteProtection(void);
  45. void vSST25SectorErase(UINT32 address);
  46.  
  47. void vSST25InitReadArray(UINT32 address);
  48. void vSST25StopReadArray(void);
  49. #define uiSST25ReadHighByteArray() uiSPIGet()
  50.  
  51. #endif //_SST25VF016_H

Código: C
  1. /*
  2.    \file SST25VF016.c  
  3.    \version 1.1
  4.    
  5.    \author Suky.
  6.    \web www.micros-designs.com.ar
  7.    \date 06/10/11  
  8.    
  9.  *- Version Log --------------------------------------------------------------*
  10.  *   Fecha       Autor                Comentarios                             *
  11.  *----------------------------------------------------------------------------*
  12.  * 06/10/11      Suky         Original (Rev 1.0) (C18)                        *
  13.  * 06/12/11              Suky             Para C32
  14.  *----------------------------------------------------------------------------* */
  15. #include "SST25VF016.h"
  16.  
  17. // *------------------------------------------------------*
  18. void vSST25Init(void){
  19.  
  20.         SST25_CS_TRIS=0;
  21.         SST25_CS=1;
  22.         OpenSPI(SPI_START_CFG_1, SPI_START_CFG_2);
  23.         SPIBRG=0; // a 80 MHz -> 40MHz SPI
  24.     vSST25ResetWriteProtection();
  25. }
  26. // *------------------------------------------------------*
  27. inline void __attribute__((always_inline)) vSPIPut(UINT8 data){
  28.     UINT8 clear;
  29.    
  30.     putcSPI((UINT8)data);
  31.     clear = getcSPI();
  32.     return;
  33. }
  34. // *------------------------------------------------------*
  35. inline UINT8 __attribute__((always_inline)) uiSPIGet(void){
  36.        
  37.         putcSPI((UINT8)0xFF);
  38.     return((UINT8)getcSPI());
  39. }
  40. // *------------------------------------------------------*
  41. void vSST25WriteByte(UINT8 data,UINT32 address){
  42.        
  43.     vSST25WriteEnable();
  44.    
  45.         SST25_CS=0;
  46.     vSPIPut(SST25_CMD_WRITE);
  47.     vSPIPut(*((UINT8 *)&address+2));
  48.     vSPIPut(*((UINT8 *)&address+1));
  49.     vSPIPut(*((UINT8 *)&address));
  50.     vSPIPut(data);
  51.     SST25_CS=1;
  52.  
  53.     // Wait for write end
  54.     while(uiSST25IsWriteBusy());
  55. }
  56. // *------------------------------------------------------*
  57. UINT8 uiSST25ReadByte(UINT32 address){
  58.     UINT8 temp;
  59.    
  60.         SST25_CS=0;
  61.     vSPIPut(SST25_CMD_READ);
  62.         vSPIPut(*((UINT8 *)&address+2));
  63.     vSPIPut(*((UINT8 *)&address+1));
  64.     vSPIPut(*((UINT8 *)&address));
  65.     temp = uiSPIGet();
  66.         SST25_CS=1;
  67.        
  68.     return (temp);
  69. }
  70. // *------------------------------------------------------*
  71. void vSST25InitReadHighArray(UINT32 address){
  72.    
  73.         SST25_CS=0;
  74.     vSPIPut(SST25_CMD_READH);
  75.         vSPIPut(*((UINT8 *)&address+2));
  76.     vSPIPut(*((UINT8 *)&address+1));
  77.     vSPIPut(*((UINT8 *)&address));
  78.     vSPIPut(0xFF); // Dummy
  79. }
  80.  
  81. void vSST25StopReadHighArray(void){
  82.         SST25_CS=1;
  83. }
  84. // *------------------------------------------------------*
  85. void vSST25WriteEnable(void){
  86.        
  87.     SST25_CS=0;
  88.     vSPIPut(SST25_CMD_WREN);
  89.     SST25_CS=1;
  90. }
  91. // *------------------------------------------------------*
  92. UINT8 uiSST25IsWriteBusy(void){
  93.     UINT8 temp;
  94.  
  95.     SST25_CS=0;
  96.     vSPIPut(SST25_CMD_RDSR);
  97.     temp = uiSPIGet();
  98.     SST25_CS=1;
  99.  
  100.     return(temp & 0x01);
  101. }
  102. // *------------------------------------------------------*
  103. void vSST25ChipErase(void){
  104.        
  105.     vSST25WriteEnable();
  106.  
  107.     SST25_CS=0;
  108.     vSPIPut(SST25_CMD_ERASE);
  109.     SST25_CS=1;
  110.  
  111.     // Wait for write end
  112.     while(uiSST25IsWriteBusy());
  113. }
  114. // *------------------------------------------------------*
  115. void vSST25ResetWriteProtection(void){
  116.        
  117.     SST25_CS=0;
  118.     vSPIPut(SST25_CMD_EWSR);
  119.     SST25_CS=1;
  120.         Nop();
  121.     SST25_CS=0;
  122.     vSPIPut(SST25_CMD_WRSR);
  123.     vSPIPut(0x00);
  124.     SST25_CS=1;
  125. }
  126. // *------------------------------------------------------*
  127. void vSST25SectorErase(UINT32 address){ // 4kByte...
  128.        
  129.     vSST25WriteEnable();
  130.    
  131.         SST25_CS=0;
  132.         vSPIPut(SST25_CMD_SER);
  133.     vSPIPut(*((UINT8 *)&address+2));
  134.     vSPIPut(*((UINT8 *)&address+1));
  135.     vSPIPut(*((UINT8 *)&address));
  136.     SST25_CS=1;
  137.  
  138.     // Wait for write end
  139.     DelayMs(100);
  140.     while(uiSST25IsWriteBusy());
  141. }


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

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Imposible leer memoria flash spi
« Respuesta #4 en: 18 de Enero de 2013, 13:47:09 »
Muchas gracias por la libreria Suky! Me sirve como punto de partida para hacer la mia :)
Creo q ya tengo mas o menos resuleto el problema. Leyendo la hoja de datos me di cuenta que este pic tiene entradas analogicas en el puerto B y por defecto estan activadas. Para ponerlas como E/S Digitales habia que modificar los registros ANCON0 y ANCON1 (ambos BANKED). La version de CCS que estaba usando no tocaba el registro ANCON1 cuando hacia setup_adc_ports(NO_ANALOGS); Luego de actualizarla a la v4.140 pude configurar el puerto B como todo digital.

Hice mas pruebas fallidas hasta que al fin pude leer el ID de la memoria (comando 0x9F). Cuando consulto el status register siempre me devuelve 0x00, supongo q esta bien. Voy a probar cambiar su valor y volver a leerlo.

En fin, adjunto el codigo que estoy usando por si a alguien le sirve.

Código: C
  1. #include <18F26J50.h>
  2. #FUSES NOWDT,INTRC_PLL_IO,NODEBUG,NOXINST,STVREN,NOPROTECT,NOFCMEN,IESO,NOIOL1WAY,NOCPUDIV,LPT1OSC,T1DIG,PLL2                
  3.  
  4. #use delay(clock=48M,INTERNAL)
  5.  
  6. #include "Hardware.h"
  7. #include ".\include\usb_cdc.h"
  8.  
  9. void init(){
  10.    // Digital IO
  11.    set_tris_a(0b1110011);  //OSC2,NC,VREG,M95_ON,LED_R,NC,NC
  12.    set_tris_b(0b11000110); //PGD,PGC,SDO2,SCK2,CS,SDI2,RX2,TX2
  13.    set_tris_c(0b10111111); //RX1,TX1,D+,D-,VUSB,NC,T1OSI,T1OSO
  14.    
  15.    setup_adc_ports(NO_ANALOGS);
  16.    setup_adc(ADC_OFF);
  17.    
  18.    setup_spi2(SPI_MASTER| SPI_L_TO_H | SPI_XMIT_L_TO_H |SPI_CLK_DIV_16);
  19.    output_high(PIN_B3);
  20. }
  21.  
  22.  
  23.  
  24. void main(){
  25.    int8 buffer[3]={0,0,0};
  26.    
  27.    delay_ms(100);
  28.    init();
  29.    usb_cdc_init();
  30.    usb_init();
  31.    
  32.    while (!usb_cdc_connected());
  33.    
  34.    delay_ms(100);
  35.    usb_task();
  36.    if(usb_enumerated()){
  37.       printf(usb_cdc_putc,"USB conectado\r\n");
  38.    }
  39.    
  40.    
  41.    while(TRUE){
  42.    
  43.       output_low(PIN_B3);
  44.       spi_write2(0x9F);
  45.       buffer[0] = spi_read2(0);
  46.       buffer[1] = spi_read2(0);
  47.       buffer[2] = spi_read2(0);
  48.       output_high(PIN_B3);
  49.      
  50.       printf(usb_cdc_putc,"recibido: %X %X %X\r\n",buffer[0],buffer[1],buffer[2]);
  51.      
  52.       output_toggle(PIN_A2);
  53.       delay_ms(500);
  54.    }
  55. }

Saludos y muchas gracias por la ayuda!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Imposible leer memoria flash spi
« Respuesta #5 en: 19 de Enero de 2013, 10:31:29 »
La libreria de CCS para esa memoria no funciona??
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: Imposible leer memoria flash spi
« Respuesta #6 en: 19 de Enero de 2013, 12:59:08 »
aprobechando el hilo queria haceros una pregunta referente a la comunicacion spi ya que me dispongo a crear una libreria para un conversor digital/analogico de texas instruments....
aqui el datasheet

bueno, pues resulta que solo con seleccionar los pines de comunicacion, podria hacer una comunicacion por software....y aqui mi pregunta... si uso un pic como por ejemplo un 16f628a que no tiene puerto spi, necesitaria declarar  #use spi(...) y spi_xfer(stream,data)?

estoy practicando la comunicacion por este puerto ya que siempre habia usado i2c y recientemente desmonte un jugete y saque 2 integrados como los del datasheet y quiero practicar este tipo de comunicacion
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Imposible leer memoria flash spi
« Respuesta #7 en: 19 de Enero de 2013, 14:10:54 »
Claro, en #use spi le indicas que pines utilizar y que modo (0, 1, 2 o 3 que en datasheet generalmente se indica como 00, 01, 10 o 11) y luego usas xfer(..). Creo recordar que spi_write y spi_read solo se usan cuando se utiliza el periférico MSSP.




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

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Imposible leer memoria flash spi
« Respuesta #8 en: 19 de Enero de 2013, 17:53:02 »
Esta es la que digo:

Código: C
  1. #ifndef SST25VF_H
  2. #define SST25VF_H
  3.  
  4. #include <stdint.h>
  5.  
  6. typedef enum _FLASH_ERASE_BLOCK_SIZE
  7. {
  8.   FLASH_ERASE_BLOCK_4KB   = 0,  // 4KB
  9.   FLASH_ERASE_BLOCK_32KB  = 1,  // 32KB
  10.   FLASH_ERASE_BLOCK_64KB  = 2   // 64KB
  11. } FLASH_ERASE_BLOCK_SIZE;
  12.  
  13. #define FLASH_PROTECT_LOCK 0x80
  14. #define FLASH_PROTECT_UNLOCK 0x00
  15. typedef enum _FLASH_PROTECT_RANGE
  16. {
  17.   FLASH_PROTECT_NONE  = 0,
  18.   FLASH_PROTECT_64KB  = 1,
  19.   FLASH_PROTECT_128KB = 2,
  20.   FLASH_PROTECT_256KB = 3,
  21.   FLASH_PRTOECT_512KB = 4,
  22.   FLASH_PROTECT_1MB   = 5,
  23.   FLASH_PROTECT_2MB   = 6,
  24.   FLASH_PROTECT_ALL   = 7
  25. } FLASH_PROTECT_RANGE;
  26.  
  27. typedef struct _FLASH_ID
  28. {
  29.    uint8_t manufacturer;
  30.    uint8_t type;
  31.    uint8_t capacity;
  32. } FLASH_ID;
  33.  
  34. #ifndef FLASH_SIZE
  35. #define FLASH_SIZE         2097152
  36. #endif
  37.  
  38. #ifndef FLASH_SECTOR_SIZE
  39. #define FLASH_SECTOR_SIZE  4096
  40. #endif
  41.  
  42. void ext_flash_init();
  43. int1 ext_flash_busy();
  44.  
  45. void ext_flash_write(uint32_t addr, uint8_t *data, uint32_t len);
  46. void ext_flash_write_byte(uint32_t addr, uint8_t data);
  47. void ext_flash_write_word(uint32_t addr, uint16_t data);
  48. void ext_flash_write_dword(uint32_t addr, uint32_t data);
  49.  
  50. void ext_flash_read(uint32_t addr, uint8_t *data, uint32_t len);
  51. uint8_t ext_flash_read_byte(uint32_t addr);
  52. uint16_t ext_flash_read_word(uint32_t addr);
  53. uint32_t ext_flash_read_dword(uint32_t addr);
  54.  
  55. void ext_flash_bulk_erase();
  56. void ext_flash_address_erase(uint32_t addr, FLASH_ERASE_BLOCK_SIZE size);
  57. void ext_flash_block_erase(uint32_t block, FLASH_ERASE_BLOCK_SIZE size);
  58.  
  59. void ext_flash_read_id(FLASH_ID *id);
  60.  
  61. void ext_flash_protect(FLASH_PROTECT_RANGE range);
  62.  
  63. // Commands
  64. #define SST25VF_READ_DATA        0x03
  65. #define SST25VF_FAST_READ_DATA   0x0B
  66. #define SST25VF_SECTOR_ERASE     0x20
  67. #define SST25VF_BLOCK_32_ERASE   0x52
  68. #define SST25VF_BLOCK_64_ERASE   0xD8
  69. #define SST25VF_BULK_ERASE       0xC7
  70. #define SST25VF_BYTE_PROG        0x02
  71. #define SST25VF_WORD_PROG        0xAD
  72. #define SST25VF_READ_STATUS      0x05
  73. #define SST25VF_WRITE_STATUS_EN  0x50
  74. #define SST25VF_WRITE_STATUS     0x01
  75. #define SST25VF_WRITE_EN         0x06
  76. #define SST25VF_WRITE_DIS        0x04
  77. #define SST25VF_READ_ID          0x9F
  78. #define SST25VF_HW_WR_STATUS     0x70
  79. #define SST25VF_POLL_WR_STATUS   0x80
  80.  
  81. #ifndef FLASH_SELECT_PIN
  82. #define FLASH_SELECT_PIN PIN_A0
  83. #endif
  84.  
  85. #define FLASH_SELECT()          output_low(FLASH_SELECT_PIN)
  86. #define FLASH_DESELECT()        output_high(FLASH_SELECT_PIN)
  87.  
  88. #ifndef FLASH_STREAM
  89.   #use spi(spi1, MODE=0, BITS=8, STREAM=FLASH_STREAM, FORCE_HW)
  90. #endif
  91.  
  92. #ifndef FLASH_XFER
  93. #define FLASH_XFER(x) spi_xfer(FLASH_STREAM, x)
  94. #endif
  95.  
  96. #define FLASH_ADDR_INVALID(addr) (addr > FLASH_SIZE)
  97.  
  98. // Must match FLASH_BLOCK_SIZE enum
  99. static uint8_t _ext_flash_block_erase_cmds[3] =
  100. {
  101.   SST25VF_SECTOR_ERASE,
  102.   SST25VF_BLOCK_32_ERASE,
  103.   SST25VF_BLOCK_64_ERASE
  104. };
  105.  
  106. // Must match FLASH_BLOCK_SIZE enum
  107. static uint8_t _ext_flash_block_sizes[3] = {4096, 32768, 65536};
  108.  
  109. static void _ext_flash_send(uint8_t cmd, int1 end);
  110. static void _ext_flash_end();
  111. static void _ext_flash_send_address(uint32_t addr);
  112.  
  113. void ext_flash_init()
  114. {
  115.    FLASH_DESELECT();
  116.    output_drive(FLASH_SELECT_PIN);
  117.    FLASH_DESELECT();
  118.    
  119.    // Make sure chip is not in the write state
  120.    _ext_flash_send(SST25VF_WRITE_DIS, TRUE);
  121.  
  122.    // Tell chip that we will poll the busy flag instead of using SDO
  123.    _ext_flash_send(SST25VF_POLL_WR_STATUS, TRUE);
  124. }
  125.  
  126. int1 ext_flash_busy()
  127. {
  128.    uint8_t status;
  129.  
  130.    FLASH_SELECT();
  131.    FLASH_XFER(SST25VF_READ_STATUS);
  132.    status = FLASH_XFER(0);
  133.    FLASH_DESELECT();
  134.  
  135.    return (bit_test(status, 0));
  136. }
  137.  
  138. void ext_flash_write(uint32_t addr, uint8_t *data, uint32_t len)
  139. {
  140.    uint8_t word[2];
  141.  
  142.    if (FLASH_ADDR_INVALID(addr))
  143.      return;
  144.      
  145.    if (len < 1)
  146.      return;
  147.  
  148.    // Enable writing to the flash
  149.    _ext_flash_send(SST25VF_WRITE_EN, TRUE);
  150.  
  151.    // Do intial write separately to allow the rest of the writes
  152.    // to be done as quickly as possible.
  153.    word[0] = 0xFF;
  154.    word[1] = 0xFF;
  155.    if (!bit_test(addr, 0))
  156.    {
  157.      word[0] = *data++;
  158.      len -= 1;
  159.    }
  160.    
  161.    if (len > 0)
  162.    {
  163.       word[1] = *data++;
  164.       len -= 1;
  165.    }
  166.  
  167.    bit_clear(addr, 0);
  168.    _ext_flash_send(SST25VF_WORD_PROG, FALSE);
  169.    _ext_flash_send_address(addr);
  170.    FLASH_XFER(word[0]);
  171.    FLASH_XFER(word[1]);
  172.    _ext_flash_end();
  173.  
  174.    // Write remaining bytes
  175.    while(len)
  176.    {
  177.       word[0] = *data++;
  178.       len -= 1;
  179.  
  180.       if (len > 0)
  181.       {
  182.          word[1] = *data++;
  183.          len -= 1;
  184.       }
  185.       else
  186.         word[1] = 0xFF;
  187.  
  188.       _ext_flash_send(SST25VF_WORD_PROG, FALSE);
  189.       FLASH_XFER(word[0]);
  190.       FLASH_XFER(word[1]);
  191.       _ext_flash_end();
  192.    }
  193.  
  194.    // Disable Writes
  195.    _ext_flash_send(SST25VF_WRITE_DIS, TRUE);
  196. }
  197.  
  198. void ext_flash_write_byte(uint32_t addr, uint8_t data)
  199. {
  200.    if (FLASH_ADDR_INVALID(addr))
  201.      return;
  202.  
  203.    // We do a byte write since it's more optimal than
  204.    // calling write_ext_flash.
  205.    _ext_flash_send(SST25VF_WRITE_EN, TRUE);
  206.  
  207.    _ext_flash_send(SST25VF_BYTE_PROG, FALSE);
  208.    _ext_flash_send_address(addr);
  209.    FLASH_XFER(data);
  210.    _ext_flash_end();
  211. }
  212.  
  213. void ext_flash_write_word(uint32_t addr, uint16_t data)
  214. {
  215.    ext_flash_write(addr, &data, 2);
  216. }
  217.  
  218. void ext_flash_write_dword(uint32_t addr, uint32_t data)
  219. {
  220.    ext_flash_write(addr, &data, 4);
  221. }
  222.  
  223. void ext_flash_read(uint32_t addr, uint8_t *data, uint32_t len)
  224. {
  225.    if (FLASH_ADDR_INVALID(addr))
  226.      return;
  227.  
  228.    _ext_flash_send(SST25VF_FAST_READ_DATA, FALSE);
  229.    _ext_flash_send_address(addr);
  230.    FLASH_XFER(0);  // dummy byte necessary for fast read
  231.    while(len--) { *data++ = FLASH_XFER(0); }
  232.    _ext_flash_end();
  233. }
  234.  
  235. uint8_t ext_flash_read_byte(uint32_t addr)
  236. {
  237.    uint8_t data = 0;
  238.    ext_flash_read(addr, &data, 1);
  239.    return data;
  240. }
  241.  
  242. uint16_t ext_flash_read_word(uint32_t addr)
  243. {
  244.    uint16_t data = 0;
  245.    ext_flash_read(addr, &data, 2);
  246.    return data;
  247. }
  248.  
  249. uint32_t ext_flash_read_dword(uint32_t addr)
  250. {
  251.    uint32_t data = 0;
  252.    ext_flash_read(addr, &data, 4);
  253.    return data;
  254. }
  255.  
  256. void ext_flash_bulk_erase()
  257. {
  258.    _ext_flash_send(SST25VF_WRITE_EN, TRUE);
  259.    _ext_flash_send(SST25VF_BULK_ERASE, TRUE);
  260. }
  261.  
  262. void ext_flash_address_erase(uint32_t addr, FLASH_ERASE_BLOCK_SIZE size)
  263. {
  264.    if (FLASH_ADDR_INVALID(addr))
  265.      return;
  266.  
  267.    _ext_flash_send(SST25VF_WRITE_EN, TRUE);
  268.  
  269.    _ext_flash_send(_ext_flash_block_erase_cmds[size], FALSE);
  270.    _ext_flash_send_address(addr);
  271.    _ext_flash_end();
  272. }
  273.  
  274. void ext_flash_block_erase(uint32_t block, FLASH_ERASE_BLOCK_SIZE size)
  275. {
  276.    ext_flash_address_erase((block * _ext_flash_block_sizes[size]), size);
  277. }
  278.  
  279. void ext_flash_read_id(FLASH_ID *id)
  280. {
  281.    _ext_flash_send(SST25VF_READ_ID, FALSE);
  282.    id->manufacturer = FLASH_XFER(0);
  283.    id->type = FLASH_XFER(0);
  284.    id->capacity = FLASH_XFER(0);
  285.    _ext_flash_end();
  286. }
  287.  
  288. void ext_flash_protect(FLASH_PROTECT_RANGE range)
  289. {
  290.    // Enable writes to the status register
  291.    _ext_flash_send(SST25VF_WRITE_EN, TRUE);
  292.  
  293.    // Unlock the protection bits
  294.    _ext_flash_send(SST25VF_WRITE_STATUS, FALSE);
  295.    FLASH_XFER(FLASH_PROTECT_UNLOCK);
  296.    _ext_flash_end();
  297.  
  298.    // Enable writes to the status register
  299.    _ext_flash_send(SST25VF_WRITE_EN, TRUE);
  300.  
  301.    // Write the new protection bits and lock them
  302.    _ext_flash_send(SST25VF_WRITE_STATUS, TRUE);
  303.    FLASH_XFER(range | FLASH_PROTECT_LOCK);
  304.    _ext_flash_end();
  305. }
  306.  
  307. static void _ext_flash_send(uint8_t cmd, int1 end)
  308. {
  309.    while(ext_flash_busy());
  310.  
  311.    FLASH_SELECT();
  312.    FLASH_XFER(cmd);
  313.    if (end) _ext_flash_end();
  314. }
  315.  
  316. static void _ext_flash_end()
  317. {
  318.    FLASH_DESELECT();
  319. }
  320.  
  321. static void _ext_flash_send_address(uint32_t addr)
  322. {
  323.    FLASH_XFER(((addr >> 16) & 0xff));
  324.    FLASH_XFER(((addr >> 8) & 0xff));
  325.    FLASH_XFER((addr & 0xff));
  326. }
  327.  
  328. #endif
« Última modificación: 19 de Enero de 2013, 18:08:28 por MGLSOFT, Razón: sacar comentarios »
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: Imposible leer memoria flash spi
« Respuesta #9 en: 20 de Enero de 2013, 07:48:35 »
Claro, en #use spi le indicas que pines utilizar y que modo (0, 1, 2 o 3 que en datasheet generalmente se indica como 00, 01, 10 o 11) y luego usas xfer(..). Creo recordar que spi_write y spi_read solo se usan cuando se utiliza el periférico MSSP.

Saludos!

gracias suky... ya esta claro... por cierto, lo siento por desviar un poco el tema del post... pido perdon al creador de este...

Código: [Seleccionar]
/////////////////////////////////////////////////////////////////////////////////
//       LIBRERIA CREADA PARA CONTROL DEL CONVERTIDOR DIGITAL/ANALOGICO
//                      DE TEXAS INSTRUMENTS TLV5617
//       tlv5617(puerto,velocidad,modo,dato)
//       puerto----------A utiliza el canal A
//                       B utiliza el canal B
//       velocidad-------FAST Convertidos en modo rapico
//                       SLOW Convertidos en modo lento
//       mode------------NORMAL Convierte el valor digital en analogico
//                       P_DOWN Pone a 0V las salidas del convertidor
//       dato------------VALOR ENTRE 0 Y 1024
/////////////////////////////////////////////////////////////////////////////////
#use spi(BAUD= 115200,DO=PIN_B1,CLK=PIN_B0, ENABLE=PIN_B2, bits= 16,IDLE=1, STREAM=TLV5617)

#define PIN_CLOCK PIN_B0
#define PIN_DO PIN_B1
#define PIN_CS PIN_B2
#define A 0b10000000
#define B 0b00000000
#define FAST 0b01000000
#define SLOW 0b00000000
#define P_DOWN 0b00100000
#define NORMAL 0b00000000

void tlv5617(int8 port,int8 speed,int8 mode,int16 data){
   int16 data_2;
  
   if(data>=1024)data=1024;
   data=data<<2;
   data_2=port+speed+mode;
   data_2=data_2<<8;
   data+=data_2;
  
   spi_xfer(data);
}

aqui el codigo de la libreria que cree... por si a alguien le interesa
está probada con un pic 16f628a

y aqui el ejemplo de como se utilizan los dos puertos analogicos de los cuales dispone el dispositivo

Código: [Seleccionar]
#include <16f628a.h>
#fuses intrc,nomclr,nowdt
#use delay(clock=4000000)
#byte puerto_a = 0x05
#byte puerto_b = 0x06
#byte CMCON = 0x1f
#include <TLV5617.C>



int8 cuenta=0;
int16 valor=0;
int16 valor_2=1023;

void main(){
   output_high(PIN_CS);
   output_low(PIN_CLOCK);
   output_low(PIN_DI);
  
   while(true){
         if(cuenta==0)++valor;
         if(cuenta==1)--valor;
         if(cuenta==1)++valor_2;
         if(cuenta==0)--valor_2;
         if(valor<=5)cuenta=0;
         if(valor>=1023)cuenta=1;
        
        
         tlv5617(A,FAST,NORMAL,VALOR);
         tlv5617(B,FAST,NORMAL,VALOR_2);
         delay_ms(200);
         output_toggle(PIN_B3);
      }
}
« Última modificación: 20 de Enero de 2013, 08:41:07 por ppyote »
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Imposible leer memoria flash spi
« Respuesta #10 en: 20 de Enero de 2013, 13:17:13 »
La libreria de CCS para esa memoria no funciona??

Me estoy enterando de la existencia de la misma jaja. Mil gracias!!
La librería dice que es para memorias SST25VF0XXB. Yo estoy usando una SST26VF016. Supongo que igualmente funcionará, no? De última tendré que hacer modificaciones mínimas.

Claro, en #use spi le indicas que pines utilizar y que modo (0, 1, 2 o 3 que en datasheet generalmente se indica como 00, 01, 10 o 11) y luego usas xfer(..). Creo recordar que spi_write y spi_read solo se usan cuando se utiliza el periférico MSSP.

Exacto. Cuando usas #use spi(), luego se utiliza la funcion xfer() tanto para lectura como escritura. Si configuras el puerto spi manualmente (con la funcion set_spi) luego utilizas spi_write() y spi_read().
En el manual de CCS esta explicado ;)


Saludos!!!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Imposible leer memoria flash spi
« Respuesta #11 en: 21 de Enero de 2013, 15:26:14 »
La librería dice que es para memorias SST25VF0XXB. Yo estoy usando una SST26VF016. Supongo que igualmente funcionará, no? De última tendré que hacer modificaciones mínimas.

Bueno, hoy lo estuve estudiando más en profundidad, y las memorias no son del todo compatibles. Algunas caracteristicas y comandos son diferentes. Sin embargo pude escribir una libreria para el SST26VF016 en poco tiempo, basandome en la del SST25VF. Todavia no logro hacer funcionar la escritura, pero todo lo demas funciona.

Cuando termine de escribirla la subo por si a alguien mas le sirve ;)

Saludos!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Imposible leer memoria flash spi
« Respuesta #12 en: 21 de Enero de 2013, 15:55:51 »
Seras agradecido, especialmente por mi que espero echar pronto a andar una de esas... :mrgreen: :mrgreen:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Imposible leer memoria flash spi
« Respuesta #13 en: 23 de Enero de 2013, 09:45:35 »
Bueno, despues de mucho rabiar con esta memoria, me di cuenta de una cosa, y lo pongo en negritas mayusculas para que otros en el futuro no tengan el mismo problema que yo:

LAS MEMORIAS SST26 NO SON SPI

O sea, tienen compatibilidad SPI para ciertas operaciones, pero fueron hechas para funcionar bajo el protocolo SQI. Y esta mas o menos claro en la hoja de datos:

Citar
Serial Interface Architecture
– Nibble-wide multiplexed I/O’s with SPI-like serial command
structure
- Mode 0 and Mode 3
– Single-bit, SPI backwards compatible
- Read, High-Speed Read, and JEDEC ID Read

O sea, las unicas operaciones que se pueden hacer por medio de SPI son lecturas. Podria emularse el SQI por software y trabajar con la memoria. Sin embargo prefiero cambiar a la SST25VF016B y no romperme mas la cabeza.

Espero que les sirva mi experiencia.. Saludos!!
« Última modificación: 23 de Enero de 2013, 09:47:41 por gera »

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Imposible leer memoria flash spi
« Respuesta #14 en: 23 de Enero de 2013, 09:49:06 »
Cual es la diferencia entre SPI y SQI ?? :shock: :shock:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.