PDA

View Full Version : how to buffer serial data on pic?



kiteman
- 21st March 2010, 10:38
Hi,
in my system with pic18f2620 (20Mhz) I must transfer serial data from serial camera to gprs modem. The camera send data with packets of 61434 bytes at 115200 baud.
My problem is to buffer data in array example .... data var byte[xxxx]
because the array is too big for a pic memory
When I receive datas in a buffer I can send it to gprs module (115200 baud)
Can someone help me to suggest an other solution to store and send?
Thankyou

Roberto

Kamikaze47
- 21st March 2010, 13:05
With that much data, you may want to consider an EEPROM chip as your buffer.

For example, the Microchip 24FC512 can store 65536 bytes so it could only just fit one of your packets.

They are pretty easy to use with the I2CREAD and I2CWRITE PBP commands.

keithdoxey
- 21st March 2010, 14:08
I would be inclined to use an SRAM chip and use an entire 8 bit port to write the data to it. EEPROM would be a lot slower and unless there is a need to retain the info permanently then static ram would be the fastest way to do it IMHO

Jerson
- 21st March 2010, 15:56
Serial or even Parallel eeprom is definitely slowww. SRAM is definitely the way to do this. The modem transfer part is bound to be intermittent and anything short of buffering the entire image before sending will cause trouble. One moment I was hoping I could suggest a MiniSD card storage; however, that too is flash memory and is slow.

If you can start and stop the camera data transfer via some protocol on your PIC device, maybe like a simple xon/xoff handshake too might help to slow down the camera side transfer to what your PIC can manage and then stream out the data on the fly.

kiteman
- 21st March 2010, 19:26
Thankyou for reply at all,
I think to transfer the data byte to byte at 115200 baud (or 57600 baud) to external memory ram, eeprom or sd card is too slowly operation in data stream. Time to write is too long betwen bytes
The camera sends the packet after a comand and I can't stop it (use tx and rx only)




Serial or even Parallel eeprom is definitely slowww. SRAM is definitely the way to do this. The modem transfer part is bound to be intermittent and anything short of buffering the entire image before sending will cause trouble. One moment I was hoping I could suggest a MiniSD card storage; however, that too is flash memory and is slow.
If you can start and stop the camera data transfer via some protocol on your PIC device, maybe like a simple xon/xoff handshake too might help to slow down the camera side transfer to what your PIC can manage and then stream out the data on the fly.

Charles Linquis
- 21st March 2010, 21:43
Writing to external RAM (static) will be plenty fast. You have 87uSec betwen bytes. That is over 400 processor cycles.

But the problem you will have with a simple parallel device is you probably don't have enough pins to do the addressing directly. If you had 3.5 free ports, you could use two for the address, one for the data, and 2 or 3 bits for the handshaking. An address latch scheme would allow you do do everything with 14 bits or so, but that would take some '374s (or equiv).

Or you could set up the address with a shift register.

languer
- 22nd March 2010, 01:14
Best option is to do a quick search for serial RAM. Few days back something pretty similar was discussed. Look at the following post: http://www.picbasic.co.uk/forum/showthread.php?t=12766

With an FRAM IC or a serial SRAM IC you can have your cake and eat it too. Need a PIC with HW SPI (4 lines), which the pic18f2620 does, and you are in business. At 14,400_bytes-sec input rate (115200bps), you could be buffering the data into RAM at a rate close to 625_bytes-sec (yes this is 5Mbit-sec). If this is not enough I do not know what is. Key in all this is the SPI bus capability in both the memory and the PIC.

FRAM is specific to RAMTRON, but is non-volatile (a bit expensive). Serial SRAM can be found from OnSemi, Microchip, and others...

kiteman
- 22nd March 2010, 16:34
I think the solutin of the serial ram is possible on spi or I2c.
What chip can I try? I need 64 Kbytes
AT24C1024 is eeprom, I hope it's too slowly also at 57600 baud from camera
thanks for reply




[QUOTE = languer; 86.812] opzione migliore è quella di fare una rapida ricerca per [I] [RAM di serie / I]. Pochi giorni indietro qualcosa di molto simile è stato discusso. Guardate il post seguente: [url] http://www.picbasic.co.uk/forum/showthread.php?t=12766 [/ url]

Con un IC FRAM o una serie di IC SRAM si può avere la botte piena e moglie ubriaca. Bisogno di un PIC con HW SPI (4 linee), che il pic18f2620 fa, e si è in affari. A 14.400 tasso di ingresso _bytes-sec (115200 bps), lei potrebbe essere il buffering dei dati in RAM ad un tasso vicino al 625_bytes-sec (sì questa è 5Mbit-sec). Se questo non è sufficiente io non so cosa sia. Chiave in tutto questo è la capacità bus SPI sia la memoria e il PIC.

FRAM è specifico per RAMTRON, ma è non volatile (un po 'costoso). SRAM seriale può essere trovato da OnSemi, Microchip, e altri ...[/ QUOTE]

languer
- 22nd March 2010, 19:12
SRAM Options
Microchip maxes out at 32 Kbytes, so you could try two of these (23A256 or 23K256). You would have to "bank select" between the two ICs using the CS lines.

OnSemi also seems to max out at 32 Kbytes (N25S830HAS22I).

You would most likely operate both these options in "Sequential/Burst Mode".

FRAM Options
RAMTRON has the FM25V05 which would allow 64 Kbytes. These do have a limit on the amount of write operations (since they do retain data after power is lost), although it is quite high.

kiteman
- 27th March 2010, 11:19
Hi Languer,
do you have some sample of program to write byte byte on the follow memory by SPI? I ordered 23A256 (2 bank)
I receive data at 57600 I have about 170 us of time to write data in memory
thankyou



SRAM Options
Microchip maxes out at 32 Kbytes, so you could try two of these (23A256 or 23K256). You would have to "bank select" between the two ICs using the CS lines.

OnSemi also seems to max out at 32 Kbytes (N25S830HAS22I).

You would most likely operate both these options in "Sequential/Burst Mode".

FRAM Options
RAMTRON has the FM25V05 which would allow 64 Kbytes. These do have a limit on the amount of write operations (since they do retain data after power is lost), although it is quite high.

languer
- 29th March 2010, 19:07
This is by no means complete code, but a starting point would be something like shown below...

The SERIN/SEROUT are defined by you application.

getData:
'[SRAM BANK 0]

'BANK SELECT
SRAM1_CS = 0 'SRAM CHIP #1 ENABLED
SRAM2_CS = 1 'SRAM CHIP #2 DISABLED

'BANK WRITE ADDRESS
spi_data = WRITE_INSTR
WriteSPI
tx_spi_data = addr.HIGHBYTE
WriteSPI
tx_spi_data = addr.LOWHBYTE
WriteSPI

'GET SERIN INTO FIRST BANK
For i = 0 to DATA_LENGTH
SERIN tx_spi_data
WriteSPI
Next i

'[SRAM BANK 1]

'BANK SELECT
SRAM1_CS = 1 'SRAM CHIP #2 DISABLED
SRAM2_CS = 0 'SRAM CHIP #1 ENABLED

'BANK WRITE ADDRESS
tx_spi_data = WRITE_INST
WriteSPI
tx_spi_data = addr.HIGHBYTE
WriteSPI
tx_spi_data = addr.LOWHBYTE
WriteSPI

'GET SERIN INTO SECOND BANK
For i = 0 to DATA_LENGTH
SERIN tx_spi_data
WriteSPI
Next i


sendData:
'[SRAM BANK 0]

'BANK SELECT
SRAM1_CS = 0 'SRAM CHIP #1 ENABLED
SRAM2_CS = 1 'SRAM CHIP #2 DISABLED

'BANK WRITE ADDRESS
spi_data = WRITE_INSTR
WriteSPI
tx_spi_data = addr.HIGHBYTE
WriteSPI
tx_spi_data = addr.LOWHBYTE
WriteSPI

'SEND SEROUT FROM FIRST BANK
For i = 0 to DATA_LENGTH
ReadSPI
SEROUT rx_spi_data
Next i

'[SRAM BANK 1]

'BANK SELECT
SRAM1_CS = 1 'SRAM CHIP #2 DISABLED
SRAM2_CS = 0 'SRAM CHIP #1 ENABLED

'BANK WRITE ADDRESS
spi_data = WRITE_INSTR
WriteSPI
tx_spi_data = addr.HIGHBYTE
WriteSPI
tx_spi_data = addr.LOWHBYTE
WriteSPI

'SEND SEROUT FROM SECOND BANK
For i = 0 to DATA_LENGTH
ReadSPI
SEROUT rx_spi_data
Next i

Necessary defines (copied from PRSTEIN's code - http://www.picbasic.co.uk/forum/showthread.php?t=12766):

' Definations for the SPI communication protocal
'------------------------------------------------------------------
SRAM1_CS VAR PORTC.0 ' SPI SRAM CHIP #1 CS PIN
SRAM1_CS_TRIS VAR TRISC.0 ' SPI SRAM CHIP #1 CS PIN DIRECTION
SRAM2_CS VAR PORTC.1 ' SPI SRAM CHIP #2 CS PIN
SRAM2_CS_TRIS VAR TRISC.1 ' SPI SRAM CHIP #2 CS PIN DIRECTION

SCK VAR PORTC.3 ' SPI CLOCK
SCK_TRIS VAR TRISC.3 ' SPI CLOCK PIN DIRECTION CONTROL
SDI VAR PORTC.4 ' SPI DATA IN
SDI_TRIS VAR TRISC.4 ' SPI DATA IN PIN DIRECTION
SDO VAR PORTC.5 ' SPI DATA OUT PIN
SDO_TRIS VAR TRISC.5 ' SPI DATA OUT PIN

WCOL VAR SSPCON.7 'SSP WRITE COLLISION
SSPEN VAR SSPCON.5 'SSP ENABLE
SSPIF VAR PIR1.3 'SSP INTERRUPT FLAG
'---------------------------------------------------------------------

'-------------SPI PORT REGISTERS SETUP----------------------------------------
SSPSTAT = %01000000 ' SAMPLE AT THE MIDDLE OF DATA OUTPUT TIME, TRANSMIT ON IDLE RISING EDGE OF SCK
SSPCON = %00100000 ' SPI MASTER MODE, CLOCK=Fosc/4 ENABLE HARDWARE SPI PORT
SSPEN = 1 ' ENABLE HARDWARE SPI PORT
'-------------------------------------------------------------------------------

'-------------INITIALIZATION--------------------------------------------------
SRAM1_CS = 1 'SRAM CHIP #1 DISABLED
SRAM2_CS = 1 'SRAM CHIP #2 DISABLED
SRAM1_CS_TRIS = 0 'OUTPUT
SRAM2_CS_TRIS = 0 'OUTPUT
SDO = 1 'START SPI PIN WITH HIGH
SDO_TRIS = 0 'OUTPUT
SDI_TRIS = 1 'INPUT


'-------------VARIABLES---------------------------------------------------------
i VAR WORD
addr VAR WORD
tx_spi_data VAR BYTE
rx_spi_data VAR BYTE
DATA_LENGTH CON 30716
'-------------------------------------------------------------------------------

The WriteSPI and ReadSPI functions below can be GOSUBs, or INLINED (i.e. pasted directly where the functions appear) for faster performance.

WriteSPI:
SSPIF = 0 'CLEAR INTERRUP FLAG
WCOL = 0 'CLEAR COLLISION BIT BEFORE WRITING TO SPI
SSPBUF = tx_spi_data 'SEND BYTE
WHILE(!SSPIF) 'WAIT FOR BYTE TO BE CLOCKED-OUT/CLOCKED-IN - THIS HAPPENS SIMULTANEOUSLY
WEND
rx_spi_data = SSPBUF 'STORE RECEIVED DATA
SSPIF = 0 'CLEAR INTERRUP FLAG
RETURN

ReadSPI:
SSPIF = 0 'CLEAR INTERRUP FLAG
WCOL = 0 'CLEAR COLLISION BIT BEFORE WRITING TO SPI
SSPBUF = 0 'SEND/CLOCK-OUT DUMMY BYTE TO CLOCK-IN RECEIVED BYTE
WHILE(!SSPIF) 'WAIT FOR 8-BITS TO BE CLOCKED-OUT/CLOCKED-IN - THIS HAPPENS SIMULTANEOUSLY
WEND
rx_spi_data = SSPBUF 'STORE RECEIVED DATA
SSPIF = 0 'CLEAR INTERRUP FLAG
RETURN

Note that there is quite a bit of optimization possible. In the places where you will be accessing the RS232 port right after the SPI commands; you could remove the wait states on the SPI commands (i.e. WHILE-WEND). All you need to make sure is that you allow sufficient time for the 8-bits to clock out; which the RS232 processing takes care of.

Also note that during this whole process you are buffering data into SRAM (or out of SRAM) sequentially (e.g. you receive an RS232 byte and store it, and again). This means that if you have qualifiers required to be read (or transmitted) at the beginning or end of your packet, then you have to handle this separately (e.g. receive-process-validate first, then enter the buffering routine).