ENC28J60 Library V3.3 full source code

General discussion on mikroBasic.
Post Reply
Author
Message
yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

ENC28J60 Library V3.3 full source code

#1 Post by yo2lio » 29 Jan 2008 00:53

Hi,

ENC28J60 Ethernet library with examples and full source code in MikroBasic language, available here :
http://www.microelemente.ro/MikroBasic/ ... amples.zip

Compiled for BICPIC4 board, MCU PIC18F8722.

Default Ip : 192.168.1.253

Code: Select all

'Ethernet library V3.3 and example for ENC28J60.

' ARP, ICMP, UDP, NTP, TCP, HTTP

' Author of this project : Florin Andrei Medrea
' Copyright (c) 2008 - YO2LIO - All Rights Reserved
' 29-Jan-2008
 
User Functions and Procedures:

   
(AddrPacket is address of received packet, TXSTART is start address of transmited packet)

- Sub Procedure Eth_SetParameters
  ' Set your IP, Mac, Mask, Gateway ... etc... here.
  ' Str2Ip("192.193.194.14",eth_ip_addr)
  ' Str2Ip("85.120.220.254",eth_ntp_addr)
  ' Str2Ip("192.193.194.1",eth_gateway)
  ' Str2Ip("255.255.255.0",eth_mask)
  ' Str2Mac("0004A300809A",eth_mac)
  ' Str2Ip("192.193.194.4",user_ip_addr)
  ' eth_port = 10001
  ' dest_port = 10001

- Sub Procedure Eth_Init_(bim byref ENC_Port as byte,dim CS,Reset as byte);
  ' Init MCU Ethernet.

- Sub Procedure Eth_Reset
  ' Reset MCU Ethernet.

- Sub Procedure Wait_For_Lan
  ' Wait fo Lan Link.

- Sub Procedure Eth_DoPacket
  ' Process incoming packets.

- Sub Function Eth_UserTCP(dim byref dest_ip_addr_T as byte[4], dim byref source_port_T, dest_port_T, len_T as word) as word
  ' This function is called by library. Put your TCP response for WEB server parameters here. See example.

- Sub Function Eth_UserUDP(dim byref dest_ip_addr_U as byte[4], dim byref dest_port_U, source_port_U, len_U as word) as word
  ' This function is called by library. Put your UDP response here. See example. ( ECHO example )

- Sub Function CopyFlashToEthMem_CP(dim start_Flash_address as longint) as word
  ' Copy Const from flash to Eth Memory and return length of Const data.
  ' Const data must be defined as STRING. (and must be zero terminated)
  ' Ex. len = CopyFlashToEthMem_CP(@httpHeader)

- Sub Function Eth_SendARP(dim byref ip_dest as byte[4]) as Boolean
  ' Get ARP request. Return True if Mac exist.
  ' Return dest. mac address in dim dest_mac as byte[6].
  ' Return dest. ip address in dim dest_ip_addr as byte[4].
  ' Ex. bol = Eth_SendARP(user_ip_addr)
  ' First function search in ArpCache (size of 9) ...

- Sub Procedure SendUDP(dim dest_port_S, source_port_S, len_data as word, dim byref data_udp as array[1472] of byte)
  ' Send UDP mesage. Max 1472 bytes.
  ' Ex. If Eth_SendARP(user_ip_addr) then SendUDP(dest_port, eth_port, 10, 'Test Test ')

- Sub Procedure Eth_SendPing(dim SlotState as boolean, dim PingSlot as Byte)
  ' Have 8 Slots available 0 .. 7 and PingCache size of 8.
  ' Ex. Eth_SendPing(Eth_SendARP(user_ip_addr),0) Send Ping at user_ip_addr and put result in Slot 0.
  ' PingCache format as
  ' PingCache[Slot].IpP as byte[4]
  ' PingCache[Slot].MacP as byte[6]
  ' PingCache[Slot].Time as word
  ' PingCache[Slot].TTL as byte.

- Sub Function Send_Ping(dim byref ip_address as byte[4]) as word
  ' Send ping at specified ip_address and return response time.
  ' Ex. PingTimeResponse = Send_Ping(user_ip_address)

- Sub Function Send_UDP(dim byref ip_address as byte[4], dim dest_port_S, source_port_S, len_data as word, dim byref data_udp as array[1472] of byte) as boolean
  ' Send UDP mesage, max 1472 bytes, at specified ip_address and return true if success.
  ' Ex. Success = Send_UDP(user_ip_addr, 10001, 9999, 10, "data data ")

- Sub Function Send_ARP(dim byref ip_address as byte[4], dim byref mac_address as byte[6]) as boolean
  ' Get MAC for specified ip_address, put result in mac_address variable and return true if success.
  ' Ex. Success = Send_ARP(user_ip_addr,reply_mac_addr)

- Sub Procedure Firewall(dim ICMP, TCP, UDP as boolean)
  ' Default all false, allow all type of packets.
  ' If ICMP = true, ignore ICMP request. Ex. Firewall(true, false, false)
  ' If TCP = true, ignore TCP packets. Ex. Firewall(false, true, false)
  ' If UDP = true, ignore UDP packets. Ex. Firewall(false, false, true)
  
- Sub Function Ntp_query as Boolean
  ' Syncronize time.
  ' Ntp address must me stored in eth_ntp_addr (see Eth_SetParameters)
  ' If syncronization was successfully Ntp_sync flag will be true.

- Sub Procedure Get_Time
  ' Transform NTP time in day/month/year ...
  ' Data will be stored in as
  ' TTime.Rfc   = Time in RFC format
  ' TTime.Unix  = Time in UNIX format
  ' TTime.Year  = Year (ex. 2007)
  ' TTime.Month = Month (ex. 07)
  ' TTime.Day   = Day (ex. 31)
  ' TTime.Hour  = Hour(ex. 12)
  ' TTime.Min   = Min (ex. 59)
  ' TTime.Sec   = Sec (ex. 32)
  ' TTime.Str   = String format max. 32 ('2007-11-24 14:25:00')
  
- Sub Procedure Eth_PutByte(dim value as byte)
  ' Put one byte in ETH memory.

- Sub Function Eth_GetByte as byte
  ' Get one byte from ETH memory.

- Sub Procedure CopyEthMemToRam(dim start_eth_address, dest_ram_address, length_w as word)
  ' Ex. CopyEthMemToRam(AddrPacket+6,@dest_mac_addr,6)

- Sub Procedure CopyEthMemToRam_Inv(dim start_eth_address, dest_ram_address, length_w as word)
  ' Ex. CopyEthMemToRam(AddrPacket+6,@data_dWord,4)
  
- Sub Procedure CopyEthMemToEthMem(dim start_eth_address, dest_eth_address, length_w as word, dim where as byte)
  ' where = 0 copy from Eth RxBuf to Eth TxBuf
  ' where = 1 copy from Eth TxBuf to Eth TxBuf
  ' Ex. CopyEthMemToEthMem(AddrPacket+38,TXSTART+28,4,0)
  
- Sub Procedure CopyRamToEthMem(dim start_ram_address, dest_eth_address, length_w as word)
  ' Ex. CopyRamToEthMem(@eth_mac,TXSTART+22,6)

- Sub Procedure CopyRamToEthMem_Inv(dim start_ram_address, dest_eth_address, length_w as word)
  ' Ex. CopyRamToEthMem(@data_dWord,TXSTART+22,4)
  
- Sub Procedure CopyRamToEthMem_CP(dim start_ram_address, length_w as word)
  ' Copy var data to Eth Memory.
  ' Ex. CopyRamToEthMem_CP(@data,46)
  
- Sub Procedure CopyRamToEthMem_CP_Inv(dim start_ram_address, length_w as word)
  ' Ex. CopyRamToEthMem_CP(@data_dWord,4)
  
- Sub Function CopyRamStringToEthMem_CP(dim byref s as string[1472]) as word
  ' Copy var data to Eth Memory and return length of var data.
  ' Var data must be defined as String. (must be zero terminated)
  ' Ex. len = CopyRamStringToEthMem_CP('data data data')
  
- Sub Procedure CopyFlashToEthMem(dim start_Flash_address as longint, dim dest_eth_address, length_w as word)
  ' Ex. CopyFlashToEthMem(@httpHeader,TXSTART+54,30)

- Sub Procedure CopyFlashToEthMem_CP(dim start_Flash_address as longint, dim length_w as word)
  ' Ex. CopyFlashToEthMem(@httpHeader,30)

- Sub Function CopyFlashStringToEthMem(dim start_Flash_address as longint, dim dest_eth_address as word) as word
  ' Copy Const from flash to Eth Memory and return length of Const data.
  ' Const data must be defined as STRING. (must be zero terminated)
  ' Ex. len = CopyFlashToEthMem_CP(@httpHeader,TXSTART+54)
  
- Sub Function CopyFlashStringToEthMem_CP(dim start_Flash_address as longint) as word
  ' Copy Const from flash to Eth Memory and return length of Const data.
  ' Const data must be defined as STRING. (must be zero terminated)
  ' Ex. len = CopyFlashToEthMem_CP(@httpHeader)
  
- Sub Procedure WriteToEthMem(dim dest_eth_address as word, dim value as byte)
  ' Ex. WriteToEthMem(TXSTART+12,$08)

- Sub Function ReadFromEthMem(dim start_eth_address as word) as byte
  ' Ex. data = ReadFromEthMem(AddrPacket+38)

- Sub Function EthMemCompareWithRam(dim start_eth_address, start_ram_address, length_w as word) as boolean
  ' Ex. bol = EthMemCompareWithRam(AddrPacket+30,@eth_ip_addr,4)

- Sub Function EthMemCompareWithFlash(dim start_eth_address as word, dim start_Flash_address as longint, dim length_w as word) as boolean
  ' Ex. bol = EthMemCompareWithFlash(AddrPacket+54, @httpHeader, 30)
Enjoy !
Last edited by yo2lio on 13 Jul 2008 20:39, edited 1 time in total.
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

guyfoc
Posts: 297
Joined: 09 Sep 2005 11:34
Location: belgium

#2 Post by guyfoc » 30 Jan 2008 11:41

hello florin thanks again for promp reply s :D
i had not many time to test and there is a lot of things to analyse ...
i test the program UDP_Send
i change for pic18f4520
1 question do you use wdt in soft ?
2 i try with timer 0 or 1 running not ok ,my ENC link LED goes off rapidely
3 i put a delay in place of the timer s and ok but eratic start up at pwr on
4 i remove the test: Wait_For_Lan
then ok ( i suppose sometime this bit is on at pwr on or not ???)
5 i must say that when i start the pwr, on my pic board, i pwron also the ENC and possible some delay in pwron init of enc must be done before soft init of ENC so put some delay..( seems better for me)
the prog used :

Code: Select all

program UDP_Send

'Ethernet library V3.3 and example for ENC28J60.

' ARP, ICMP, UDP, NTP, TCP, HTTP

' Author of this project : Florin Andrei Medrea
' Copyright (c) 2008 - YO2LIO - All Rights Reserved
' 29-Jan-2008

' Send UDP data to computer ....

' Attention !!!! This program uses TMR1 or TMR2 interrupt at 1 ms !!!!!!!!!
'  User can select between TMR1 and TMR2 interrupt '

#DEFINE TMR1_Interrupt
'#DEFINE TMR2_Interrupt

include "mb_aditional_string_util" ' Don't touch this lines !!!!!
include "lib1_ENC28J60_V3_3"
include "enc_lib_user"
include "lib2_ENC28J60_V3_3"

dim  user_ip_addr as byte[4]
     counter1 as word
     Success as boolean
     data_user as string[100]

#IFDEF TMR1_Interrupt
sub procedure interrupt ' with TMR1 timer
  if PIR1.TMR1IF = 1 then      ' 1 ms TMR1 Q=40 MHz
    PIR1.TMR1IF=0
    TMR1L = 0x1E
    TMR1H = 0xFB
    CounterTask  ' must called at 1ms
  end if
end sub

Sub Procedure Init ' with TMR1 timer interrupt
  ClrWdt
  WDTCON = 1                 'soft wdt ena if diss in hwd
  TMR1L = 0x1E
  TMR1H = 0xFB               ' 1 ms TMR1 Q=40 MHz prescaler 8
  PIE1 = %00000001
  T1CON = %10110001          ' prescaler /8 in 16 bit mod
  INTCON = %11000000     ' en glob+ perif int  TMR1 int at 1 ms
End Sub
#ENDIF

#IFDEF TMR2_Interrupt
sub procedure interrupt ' with TMR2 timer
  if TestBit(PIR1,TMR2IF) = 1 then      ' 1 ms TMR2 Q=40 MHz
    PIR1.TMR2IF=0
    CounterTask  ' must called at 1ms
  end if
end sub

Sub Procedure Init ' with TMR2 timer interrupt
  ClrWdt
  WDTCON = 1            'soft wdt ena if diss in hwd
  PIE1 = %00000010      'ena timer 2 int when = to pr2
  PR2 = 250             ' timer 2 periode reg pwm comp
  T2CON = %01001001          ' prescaler 4, poscaler 10
  TMR2 = 0
  T2CON.TMR2ON = 1           ' start TMR2
  INTCON = %11000000         ' intrerupere TMR2 la 1 ms
End Sub
#ENDIF

Sub Procedure Eth_SetParameters   ' set your parameters here
  Str2Ip("10.1.1.2",eth_ip_addr)
  Str2Ip("10.1.1.254",eth_gateway)
  Str2Ip("255.255.255.0",eth_mask)
  Str2Mac("0014A576193E",eth_mac)
  Str2Ip("10.1.1.1",user_ip_addr)

  eth_port = 10001      ' port used by pic ENC (and setted in udp terminal on the pc)
  'dest_port = 10001
  dest_port = 6767        'port used by my pc eth cd and udp terminal
end sub

main:
  CMCON = CMCON or $07                 ' turn off comparators
  ADCON1 = $0F                         ' all pins digital
  'MEMCON.EBDIS = 1                    ' disable external memory bus not for 18f4520
  Delay_ms(2000)                       ' wait pwr on ENC Init
  Init
  Spi_Init_Advanced(MASTER_OSC_DIV4, DATA_SAMPLE_MIDDLE, CLK_IDLE_LOW, LOW_2_HIGH)
  Eth_SetParameters
  Eth_Init_(PORTC, 1, 0)'(ENC_Port, CS, Reset)
'  Firewall(true,false,false)
  'Wait_For_Lan
  data_user = "Some data ..... here ...."
  counter1 = 5000
  while true
    Eth_DoPacket ' process incoming packets
    'if counter1 > 5000 then  'repeat at 5000 ms
    '  counter1 = 0
     Delay_ms(5000)
     Success = Send_UDP(user_ip_addr, dest_port, eth_port, Str_Len(data_user), data_user)
                         ' Send UDP data ...
   ' end if
  wend
end.
when more time will try to modif the timer to test ( i see you use some part i do not know )
73s guy
things we are knowing are always easy

yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

#3 Post by yo2lio » 30 Jan 2008 12:16

Try to use TMR2, I don't use TMR1 !!!

Yes I use WDT in my lib.

Code: Select all

  WDTCON = 1                 'soft wdt ena if diss in hwd
You must set prescaler for WDT in configuration, put 1024 value for PIC18F4520.

All examples was tested with TMR2.
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

guyfoc
Posts: 297
Joined: 09 Sep 2005 11:34
Location: belgium

#4 Post by guyfoc » 30 Jan 2008 19:23

try a lot of thing timer 1 or timer 2 with or without wdt not ok
sometime enc send 1 time the udp msg but no more and sometimes my link led stop to light on the enc bd

rem i do not see where you inc counter1 ?

i include it in the int rtn but not ok
will see again tomorow

where do you start the wdt in soft ???
reg guy
things we are knowing are always easy

yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

#5 Post by yo2lio » 30 Jan 2008 19:43

Sorry, I forgot to increment counter1 in interrupt routine ... :oops:

Code: Select all

program UDP_Send

'Ethernet library V3.3 and example for ENC28J60.

' ARP, ICMP, UDP, NTP, TCP, HTTP

' Author of this project : Florin Andrei Medrea
' Copyright (c) 2008 - YO2LIO - All Rights Reserved
' 29-Jan-2008

' Send UDP data to computer ....

' Attention !!!! This program uses TMR1 or TMR2 interrupt at 1 ms !!!!!!!!!
'  User can select between TMR1 and TMR2 interrupt '

'#DEFINE TMR1_Interrupt
#DEFINE TMR2_Interrupt

include "mb_aditional_string_util" ' Don't touch this lines !!!!!
include "lib1_ENC28J60_V3_3"
include "enc_lib_user"
include "lib2_ENC28J60_V3_3"

dim  user_ip_addr as byte[4]
     counter1 as word
     Success as boolean
     data_user as string[100]

#IFDEF TMR1_Interrupt
sub procedure interrupt ' with TMR1 timer
  if PIR1.TMR1IF = 1 then      ' 1 ms TMR1 Q=40 MHz
    PIR1.TMR1IF=0
    TMR1L = 0x1E
    TMR1H = 0xFB
    CounterTask  ' must called at 1ms
    inc(counter1)
  end if
end sub

Sub Procedure Init ' with TMR1 timer interrupt
  ClrWdt
'  WDTCON = 1
  TMR1L = 0x1E
  TMR1H = 0xFB               ' 1 ms TMR1 Q=40 MHz prescaler 8
  PIE1 = %00000001
  T1CON = %10110001          ' prescaler 8 16 bit mod
  INTCON = %11000000         ' intrerupere TMR1 la 1 ms
End Sub
#ENDIF

#IFDEF TMR2_Interrupt
sub procedure interrupt ' with TMR2 timer
  if TestBit(PIR1,TMR2IF) = 1 then      ' 1 ms TMR2 Q=40 MHz
    PIR1.TMR2IF=0
    CounterTask  ' must called at 1ms
    inc(counter1)
  end if
end sub

Sub Procedure Init ' with TMR2 timer interrupt
  ClrWdt
'  WDTCON = 1
  PIE1 = %00000010
  PR2 = 250
  T2CON = %01001001          ' prescaler 4, poscaler 10
  TMR2 = 0
  T2CON.TMR2ON = 1           ' start TMR2
  INTCON = %11000000         ' intrerupere TMR2 la 1 ms
End Sub
#ENDIF

Sub Procedure Eth_SetParameters   ' set your parameters here
  Str2Ip("192.168.1.253",eth_ip_addr)
  Str2Ip("192.168.1.1",eth_gateway)
  Str2Ip("255.255.255.0",eth_mask)
  Str2Mac("0004A3008080",eth_mac)
  Str2Ip("192.168.1.2",user_ip_addr)

  eth_port = 10001
  dest_port = 10001
end sub

main:
'  CMCON = CMCON or $07                 ' turn off comparators
'  ADCON1 = $0F                         ' all pins digital
'  MEMCON.EBDIS = 1                     ' disable external memory bus
  Init
  Spi_Init_Advanced(MASTER_OSC_DIV4, DATA_SAMPLE_MIDDLE, CLK_IDLE_LOW, LOW_2_HIGH)
  Eth_SetParameters
  Eth_Init_(PORTC, 1, 0)'(ENC_Port, CS, Reset)
'  Firewall(true,false,false)
  Wait_For_Lan
  data_user = "Some data ..... here ...."
  counter1 = 5000
  while true
    Eth_DoPacket ' process incoming packets
    if counter1 > 5000 then  'repeat at 5000 ms
      counter1 = 0
      Success = Send_UDP(user_ip_addr, dest_port, eth_port, Str_Len(data_user), data_user)
      ' Send UDP data ...
    end if
  wend
end.
This example, at me, work ok now ! :oops:
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

#6 Post by yo2lio » 30 Jan 2008 20:06

Library and examples updated.

Watchdog is disabled hardware and software.

Attention : This library must use Timer1 or Timer2 interrupt at 1ms !

If your SPI hardware don't work at 10 Mbps then use this routine for init SPI :

Code: Select all

Spi_Init_Advanced(MASTER_OSC_DIV64, DATA_SAMPLE_MIDDLE, CLK_IDLE_LOW, LOW_2_HIGH)
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

guyfoc
Posts: 297
Joined: 09 Sep 2005 11:34
Location: belgium

#7 Post by guyfoc » 31 Jan 2008 09:33

my test until now: config word;
hspll osc on
wdt off
mclr on
lvp off
xinst off
18f4520

with the add of inc(counter1) in int rtn : not ok
i test it yesterday also without success

with the delay it is only ok if:

1
Spi_Init_Advanced(MASTER_OSC_DIV64, DATA_SAMPLE_MIDDLE, CLK_IDLE_LOW, LOW_2_HIGH)
does not work at all
but SPI_init is ok ( also your 1st div/4 ...is ok and normaly = to the spi_init)
2 if i remove the 'Wait_For_Lan : always ok
if i keep it sometime yes or need a mclr reset of pic sometime to start
i look again this strange behaviour... :D
things we are knowing are always easy

yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

#8 Post by yo2lio » 31 Jan 2008 09:45

....

It's possible to be a BUG in PIC18F4520 !!! Microchip BUG !!!

I have in the past the same problems with PIC18F2620.

But with PIC18F452, PIC18F8722 everything it's OK !!

I can't explain this :oops:

For test include this part :

Code: Select all

  TRISA.5 = 0 'possible bug in SPI Microchip
  nop
  PORTA.5 = 0 'possible bug in SPI Microchip
  nop
  TRISC.3 = 0
  nop
  TRISC.4 = 1
  nop
  TRISC.5 = 0
  nop
  SPI_Init

'the rest of code ....
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

guyfoc
Posts: 297
Joined: 09 Sep 2005 11:34
Location: belgium

#9 Post by guyfoc » 31 Jan 2008 14:06

i found something strange for me;

i include a port d.1 toggle led to see if prob with timer or not
seems not to be a timer prob because sometime its send 1 time a udp msg then stop with sometime the d.1 led toggling and link led on the enc off
sometime the d.1 led is stopped than the timer also

the solution:
if i put a delays mini 4000 ms before the call to send the udp its is ok
( rem with the delay only without the counter1 used it is ok also)

Code: Select all

main:
  CMCON = CMCON or $07                 ' turn off comparators
  ADCON1 = $0F                         ' all pins digital
  trisD=0
  'MEMCON.EBDIS = 1                    ' disable external memory bus not for 18f4520
  Delay_ms(1000)                       ' wait pwr on ENC Init
  Init
  'Spi_Init_Advanced(MASTER_OSC_DIV4, DATA_SAMPLE_MIDDLE, CLK_IDLE_LOW, LOW_2_HIGH)
  'Spi_Init_Advanced(MASTER_OSC_DIV64, DATA_SAMPLE_MIDDLE, CLK_IDLE_LOW, LOW_2_HIGH)
  SPI_init
  'delay_ms(1000)
  Eth_SetParameters
 'delay_ms(1000)
  Eth_Init_(PORTC, 1, 0)'(ENC_Port, CS, Reset)
'  Firewall(true,false,false)
  'delay_ms(1000)
 ' Wait_For_Lan
  data_user = "Some data ..... here ...."
  counter1 = 5000
  while true
    Eth_DoPacket ' process incoming packets
    if counter1 > 5000 then
      counter1 = 0
      if portD.1=0 then portD.1=1
           else portD.1=0
      end if
    'end if
     delay_ms(4000)   ' mini to work ok
     'Delay_ms(5000)
     Success = Send_UDP(user_ip_addr, dest_port, eth_port, Str_Len(data_user), data_user)
                         ' Send UDP data ...
    end if
  wend
end.
things we are knowing are always easy

guyfoc
Posts: 297
Joined: 09 Sep 2005 11:34
Location: belgium

#10 Post by guyfoc » 31 Jan 2008 14:16

tried your magic solution
:D :D :D
you are the best
it work and with the Wait_For_Lan also included
:D :D
things we are knowing are always easy

yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

#11 Post by yo2lio » 31 Jan 2008 15:01

guyfoc wrote:tried your magic solution
:D :D :D
you are the best
it work and with the Wait_For_Lan also included
:D :D
Thanks for your appreciations !

This Microchip BUG isn't mentioned in MCU's ERATA .... or maybe is a trick !?

Conclusion : Code don't work without clearing TRISA.5 and PORTA.5 before initializing SPI module ! PORTA.5 for some MCU's is SS pin from SPI module, but this pins is not used !


Referred to PIC18F4620, PIC18F2620, PIC18F4520, PIC18F2520 ... maybe more but is not tested ...

Works great without clearing TRISA.5 and PORTA.5 with PIC18F252, PIC18F452 ...

My library will be updated in few hour with this trick !

Enjoy the library !
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

guyfoc
Posts: 297
Joined: 09 Sep 2005 11:34
Location: belgium

#12 Post by guyfoc » 31 Jan 2008 17:54

thanks again
i test rapidely the miniweb server ex and same conclusion for the bug
rem using the
Spi_Init_Advanced(MASTER_OSC_DIV64, DATA_SAMPLE_MIDDLE, CLK_IDLE_LOW, LOW_2_HIGH)

does not work for me

rem you can also add this timer method working

Code: Select all

dim C1 as word  absolute $FBE   ' memory address for CCPR1 register ($FBE + $FBF)  for 18F4520
'dim C1 as word absolute $15    ' memory address for CCPR1 register ($15 + $16)  for 16F877

Code: Select all

#IFDEF MY TMR1 Interrupt
Sub procedure interrupt
 if PIR1.CCP1IF = 1 then     ' If Compare interrupt,
    PIR1.CCP1IF = 0          ' clear CCP1 interrupt flag
    CounterTask  ' must called at 1ms
    inc(counter1)
 end if
end sub
Sub Procedure Init
 ClrWdt
' WDTCON = 1
 T1CON = %00110000      ' prescaler = 8; timer1=off
 TMR1L = 0              ' clear timer1
 TMR1H = 0              '
 CCP1CON = %00001011    ' special event trigger enabled
 'C1 = 50000              '40mhz presc/8 40ms /cnt
 C1 = 1250                '1ms
 PIE1.CCP1IE = 1        ' enable CCP1 interrupt
 PIR1.CCP1IF = 0        ' clear CCP1 interrupt flag
 T1CON.TMR1ON = 1       ' start Timer1
 INTCON.GIE = 1         ' enable GIE (global interrupt)
 INTCON.PEIE = 1        ' enable PEIE (peripheral interrupt)

end sub
#ENDIF
tested the 3
t1 gives about 5,013 sec
t2 gives about 5,0194 sec
myt1 5,00042 sec for the udp loop ( but 10 rom more)
just for info :D 73s
things we are knowing are always easy

yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

#13 Post by yo2lio » 31 Jan 2008 18:14

guyfoc wrote:tested the 3
t1 gives about 5,013 sec
t2 gives about 5,0194 sec
myt1 5,00042 sec for the udp loop ( but 10 rom more)
Come on , this is not atomic clock ! :D
Thanks for suggestion !

BTW:

Code: Select all

Spi_Init_Advanced(MASTER_OSC_DIV4, DATA_SAMPLE_MIDDLE, CLK_IDLE_LOW, LOW_2_HIGH)

work at you ?
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

guyfoc
Posts: 297
Joined: 09 Sep 2005 11:34
Location: belgium

#14 Post by guyfoc » 01 Feb 2008 09:49

yes /4 works ( i thing it is the default for SPI_init also)
the /64 does not work
things we are knowing are always easy

yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

#15 Post by yo2lio » 01 Feb 2008 11:49

guyfoc wrote:yes /4 works ( i thing it is the default for SPI_init also)
the /64 does not work
You are right ! New ERATA available for PIC18F4520 family (1/17/2008) :
http://ww1.microchip.com/downloads/en/D ... 80209h.pdf

:evil: :evil: :evil:

2. Module: MSSP
With MSSP in SPI Master mode, FOSC/64 or Timer2/2 clock rate, and CKE = 0, a write collision may occur if SSPBUF is loaded immediately after the transfer is complete. A delay may be required after the MSSP Interrupt Flag bit, SSPIF, is set or the Buffer Full bit, BF, is set and before writing SSPBUF. If the delay is insufficiently short, a write collision may occur, as indicated by the WCOL bit being set.


Till now, nothing about clearing TRISA.5 and PORTA.5 (SS pin) before Init_Spi !
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

Post Reply

Return to “mikroBasic General”