Revision: 1167
Author: jsuijs
Date: Wed Aug  5 23:15:29 2009
Log: delay calibrate project
http://code.google.com/p/jallib/source/detail?r=1167

Added:
  /trunk/project/delay_calibrate
  /trunk/project/delay_calibrate/delay_calibrate.jal
  /trunk/project/delay_calibrate/serial_hardware_hacked.jal

=======================================
--- /dev/null
+++ /trunk/project/delay_calibrate/delay_calibrate.jal  Wed Aug  5 23:15:29  
2009
@@ -0,0 +1,261 @@
+-- delay_calibrate.jal
+--
+-- This program calls delays and uses timer1 to measure how long they take.
+-- The target clock can be changed to any desired value, without the need
+-- to change the real clock of the target. This works since both the timer
+-- (used for measuring) and the cpu (executing the delay) use the same  
clock.
+-- the constant hacked_target_clock must be set at the real clock rate to
+-- calculate the proper baudrate of the serial port.
+
+
+
+include 16f88
+
+;--
+;-- This setup assumes a 20 MHz resonator or crystal
+;-- is connected to pins OSC1 and OSC2.
+pragma target OSC       HS             -- HS crystal or resonator
+pragma target clock     20_000_000     -- oscillator frequency
+pragma target WDT       disabled       -- no watchdog
+pragma target LVP       disabled       -- no low-voltage programming
+pragma target CCP1MUX   RB3            -- ccp1 pin on B3
+
+--
+-- This setup uses the internal oscillator
+;pragma target OSC       INTOSC_NOCLKOUT   -- HS crystal or resonator
+;pragma target clock     8_000_000         -- oscillator frequency
+;pragma target WDT       disabled          -- no watchdog
+;pragma target LVP       disabled          -- no low-voltage programming
+;pragma target CCP1MUX   RB3               -- ccp1 pin on B3
+;OSCCON_IRCF = 7                           -- set prescaler to 1 (8 MHz)
+
+
+;@jallib section serial
+const serial_hw_baudrate = 115_200
+const hacked_target_clock = 20_000_000
+
+-- setup serial (see echo.jal for more details);@jallib section serial
+include serial_hardware_hacked
+serial_hw_init()
+
+include print
+include ndelay
+
+;var word TMR1 at TMR1L
+
+t1con = 0x01 ; TMR1ON, prescaler 1 (1 tick = 0.2 us)
+
+
+procedure aap (byte in abc) is
+   var volatile word xyz = abc
+end procedure
+
+var volatile word noot
+var volatile byte mies
+
+;aap(noot)
+;
+;aap(1000)
+;
+;noot = mies
+;mies = noot
+
+const byte m1[] = "Test "
+const byte m2[] = " us, measured "
+const byte m3[] = " us"
+
+procedure report_delay( word in setpoint, word in interval) is
+
+   if (interval > 32768) then
+      interval = 0 - interval
+   end if
+
+   ; calculate tick time in 100ns steps
+   var dword tick = target_clock
+   tick = 40_000_000 / tick
+   case ((t1con & 0x30) / 0x10) of
+      1 : block
+         tick = tick * 2
+      end block
+
+      2 : block
+         tick = tick * 4
+      end block
+
+      3 : block
+         tick = tick * 8
+      end block
+
+   end case
+
+   print_string(serial_hw_data, m1)
+
+   print_dword_dec(serial_hw_data, setpoint)
+
+   print_string(serial_hw_data, m2)
+   print_word_dec(serial_hw_data, (interval * tick) / 10)
+   serial_hw_data = "."
+   print_word_dec(serial_hw_data, (interval * tick) % 10)
+
+
+   print_string(serial_hw_data, m3)
+
+;   print_byte_dec(serial_hw_data, tick)
+
+   print_crlf(serial_hw_data)
+
+end procedure
+
+
+
+var word pre_timer
+var word post_timer
+forever loop
+
+   const byte str0[] = "Target clock: "
+   print_string(serial_hw_data, str0)
+
+   print_dword_dec(serial_hw_data, target_clock)
+
+   const byte str1[] = " ----------------------------\r\nTest us  
delays\r\n"
+   print_string(serial_hw_data, str1)
+
+   t1con = 0x00 ; TMR1 off, prescaler 1 (1 tick = 0.2 us @ 20 MHz, 32k =  
6,5 ms )
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   -- no delay
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(0, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_1us()
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(1, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_2us()
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(2, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_5us()
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(5, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_9us()
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(9, post_timer - pre_timer)
+
+   const byte str2[] = "Test 10us delays\r\n"
+   print_string(serial_hw_data, str2)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_10us(1)
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(10, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_10us(2)
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(20, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_10us(5)
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(50, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_10us(10)
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(100, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_10us(20)
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(200, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_10us(50)
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(500, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_10us(100)
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(1000, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_10us(200)
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(2000, post_timer - pre_timer)
+
+   const byte str3[] = "Test 1ms delays\r\n"
+   print_string(serial_hw_data, str3)
+
+   t1con = 0x30 ; TMR1 off, prescaler 8 (1 tick = 1.6 us @ 20 MHz, 32k =  
52 ms )
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_1ms(1)
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(1_000, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_1ms(2)
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(2_000, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_1ms(5)
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(5_000, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_1ms(10)
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(10_000, post_timer - pre_timer)
+
+   pre_timer = TMR1
+   T1CON_TMR1ON = true
+   delay_1ms(20)
+   T1CON_TMR1ON = false
+   post_timer = TMR1
+   report_delay(20_000, post_timer - pre_timer)
+
+   delay_100ms(10)
+
+end loop
=======================================
--- /dev/null
+++ /trunk/project/delay_calibrate/serial_hardware_hacked.jal   Wed Aug  5  
23:15:29 2009
@@ -0,0 +1,266 @@
+-- Title: USART hardware control
+-- Author: Stef Mientki, Copyright (c) 2002..2006, all rights reserved.
+-- Adapted-by: Sebastien Lelong.
+-- Compiler: >=2.4g
+--
+-- This file is part of jallib (http://jallib.googlecode.com)
+-- Released under the ZLIB license  
(http://www.opensource.org/licenses/zlib-license.html)
+--
+-- Description: USART hardware control.
+-- Routines for sending and receiving through the PIC-usart,
+-- both asynchrone and synchrone are supported.
+-- Baudrate can simply be set through a human constant,
+-- because the baudrate depending registers are calculated by this unit.
+-- Baudrate is calculated, starting at the high baudrate flag,
+-- which will ensure the highest possible accuracy.
+--
+-- TODO: should this be configurable ?
+-- Transmission parameters are 8 databits, 1 stopbit, no parity, no  
handshake.
+--
+
+if (defined(usart_hw_serial) == false) then
+   const bit usart_hw_serial = true -- default is async mode (not sync)
+end if
+
+procedure _calculate_and_set_baudrate() is
+   const max_deviation = 5  -- maximum % deviation of the realized baudrate
+
+   if usart_hw_serial then
+      -- SPBRG = ( Fosc / ( 4 * Baudrate ) ) -1
+      -- first try high baudrate, will generate highest accuarcy
+      -- to get the right rounding (5 + 10*f(x)) /10
+      const usart_div =((5 + ( ( 10 * hacked_target_clock ) / ( 16 *  
serial_hw_baudrate ))  ) / 10 ) - 1
+
+      -- special case if divider is 0,
+      -- test if deviation is not too much
+      if usart_div <= 0 then
+         if (100 * (serial_hw_baudrate - (hacked_target_clock / 16) )) /  
serial_hw_baudrate >= max_deviation then
+            pragma error  -- asynchronous baudrate is too high
+         end if
+      end if
+
+      -- if divider small enough,
+      -- calculate divider and set high-speed
+      const real_baud = hacked_target_clock / 16 / (usart_div + 1)
+      if usart_div <= 255 then
+         if (real_baud > serial_hw_baudrate) then
+            if (100 * (real_baud - serial_hw_baudrate) /  
serial_hw_baudrate >= max_deviation) then
+               pragma error  -- asynchronous baudrate deviation is too  
large
+            end if
+         else
+            if (100 * (serial_hw_baudrate - real_baud) /  
serial_hw_baudrate >= max_deviation) then
+               pragma error  -- asynchronous baudrate deviation is too  
large
+            end if
+         end if
+
+         if usart_div >= 0 then
+            SPBRG = usart_div
+         else
+            SPBRG = 0
+         end if
+         TXSTA_BRGH = true
+         -- try the low-speed mode
+      else
+           const usart_div_low = ((((10 * hacked_target_clock) / ( 64 *  
serial_hw_baudrate )) + 5 ) / 10) - 1
+         -- here divider will never be 0
+         -- but special case to consider,
+         -- if baudrate is just a little too low
+         if (usart_div_low > 255) & (100 * ((hacked_target_clock / (64 *  
256 )) - serial_hw_baudrate)) / serial_hw_baudrate < max_deviation then
+            SPBRG = 255
+            TXSTA_BRGH = false
+            -- now calculate divider and set high-speed / low-speed bit
+           elsif usart_div_low <= 255 then
+            if usart_div_low >= 0 then
+               SPBRG = usart_div_low
+            else
+               SPBRG = 0
+            end if
+            TXSTA_BRGH = false
+           else
+            pragma error -- asynchronous baudrate is too low
+           end if
+      end if
+
+   else  -- synchronous mode
+      const usart_div_sync = ( hacked_target_clock / ( 4 *  
serial_hw_baudrate )) - 1
+
+      -- special case if divider is 0 or negative
+      -- test if baudrate is a little bit too high
+      if usart_div_sync <= 0 then
+         if (100 * (serial_hw_baudrate - (hacked_target_clock / 4 ) )) /  
serial_hw_baudrate >= max_deviation then
+            pragma error  -- synchronous baudrate is too high
+         end if
+      end if
+
+      -- special case to consider,
+      -- if baudrate is just a little too high
+      if (usart_div_sync > 255) & (100 * ((hacked_target_clock / (4 *  
256)  ) - serial_hw_baudrate)) / serial_hw_baudrate < max_deviation then
+         SPBRG = 255
+      elsif usart_div_sync <= 255 then
+         if SPBRG >= 0 then
+            SPBRG = usart_div_sync
+         else
+            SPBRG = 0
+         end if
+      else
+         pragma error -- synchronous baudrate is too low
+      end if
+   end if
+
+end procedure
+
+
+
+-- Initializes the serial port, calculates baudrate registers.
+procedure serial_hw_init() is
+   -- Calculate and Load baudrate generator
+   _calculate_and_set_baudrate()
+
+   -- disable all USART interrupts
+   PIE1_RCIE = false
+   PIE1_TXIE = false
+
+   -- Enable transmitter : TXSTA_TXEN=1 (preserve TXSTA_BRGH)
+   TXSTA_TXEN = true
+
+   -- Enable serial port : RCSTA_SPEN=1
+   -- Enable receiving   : RCSTA_CREN=1
+   RCSTA = 0x90
+
+end procedure
+
+
+-- Disables USART so ports can be used (temporary) for other purposes.
+-- USART can be enabled again by calling serial_hw_enable()
+procedure serial_hw_disable() is
+   -- wait till running transmissions are finished
+   while !TXSTA_TRMT loop end loop
+   -- Disable Serial port:
+   RCSTA_SPEN = false
+end procedure
+
+
+-- Enables USART
+procedure serial_hw_enable() is
+   -- Enable Serial port
+   RCSTA_SPEN = true
+end procedure
+
+
+-- -----------------------------------------------------------------------
+-- serial_hw_write - write char to serial port, blocking
+-- -----------------------------------------------------------------------
+-- Asynchronuous serial send routine, using the TX pin
+-- Sends byte X (8 bit with no parity) to the serial port
+-- First checks (and waits if necessary) if transmit buffer is empty
+-- -----------------------------------------------------------------------
+procedure serial_hw_write(byte in data) is
+   -- wait until TXREG is empty
+   while ! PIR1_TXIF loop end loop
+   -- then put new byte in TXREG (prepare for transmission)
+   TXREG = data
+end procedure
+
+
+-- like Serial_H_write, but then with a word as input
+-- The MSB is outputed first
+procedure serial_hw_write_word(word in data) is
+   var byte DX[2] at data
+   -- can be blocked by debugging
+   while ! PIR1_TXIF loop end loop
+   TXREG = DX[1]
+   asm nop  -- this is necessary for damned good optimized compilers
+            -- loading of the TXREG doesn't immediatly set PIR1_TXIF !!!!
+   while ! PIR1_TXIF loop end loop
+   TXREG = DX[0]
+end procedure
+
+
+-- -----------------------------------------------------------------------
+-- _serial_hw_read - internal use only!
+-- -----------------------------------------------------------------------
+-- (using this inline function for serial_hw_data'get saves a stack level)
+-- Returns true if a character was received, otherwise returns false.
+-- Overrun error flag is cleared.
+-- -----------------------------------------------------------------------
+function _serial_hw_read(byte out data) return bit is
+   pragma inline
+
+   -- test if byte available, and if so,
+   -- get byte and transport to outer world
+   if PIR1_RCIF then
+      data = RCREG
+      PIR1_RCIF   = false       -- [email protected] 12-sept-08
+   else
+      return false  ;result = false
+   end if
+
+   if RCSTA_OERR then
+      RCSTA_CREN = false
+      RCSTA_CREN =true
+   end if
+
+   return true
+end function
+
+
+-- -----------------------------------------------------------------------
+-- serial_hw_read - read char if available (non-blocking)
+-- -----------------------------------------------------------------------
+-- Returns true if a character was received, otherwise returns false.
+-- Overrun error flag is cleared.
+-- -----------------------------------------------------------------------
+function serial_hw_read(byte out data) return bit is
+   return _serial_hw_read(data)
+end function
+
+
+-- Here Serial read and write are definied as pseudo variables
+-- so you use them as normal vars, like
+--  * wait for character being received,
+--  * then echo the inverted character
+-- {{{
+-- serial_hw_data = ! serial_hw_data
+-- }}}
+--
+-- these procedures will wait till they can perform their action
+-- therefore it's better to use to following construct
+-- {{{
+-- -- if charater received, echo the inverted character
+-- if  serial_hw_data_available then
+--     serial_hw_data = ! serial_hw_data
+-- end if
+-- -- do other things
+-- }}}
+--
+procedure serial_hw_data'put(byte in data) is
+   serial_hw_write(data)
+end procedure
+
+
+function serial_hw_data'get() return byte is
+   var byte data
+   while ! _serial_hw_read(data) loop end loop
+   return data
+end function
+
+
+-- -----------------------------------------------------------------------
+-- raw interface
+-- -----------------------------------------------------------------------
+
+-- some variables made available under a general (pic-independant) name
+var volatile bit serial_hw_data_available is PIR1_RCIF
+var volatile bit serial_hw_data_ready is PIR1_TXIF
+
+-- These are real raw procedures, declared as pseudo variables
+-- the user is totally responsible for testing the transmit/receive
+-- flag before using these functions
+procedure serial_hw_data_raw'put(byte in data) is
+   TXREG = data
+end procedure
+
+function serial_hw_data_raw'get() return byte is
+   return RCREG
+end function
+

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/jallib?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to